Make parameters per activity
This commit is contained in:
@@ -52,7 +52,7 @@
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
<p class="text-xs label">
|
||||
{#if !selected.cfg.disableGeneration && allStandards
|
||||
{#if !selected.cfg.activity[selected.activity].disableGeneration && allStandards
|
||||
.byActivity(selected.activity)
|
||||
.getMetadata().generators.length}
|
||||
(Generated data: {allStandards
|
||||
@@ -87,7 +87,7 @@
|
||||
? parseFloat(kgToLb(standard.metrics.weight).toFixed(2))
|
||||
: "None"}</th
|
||||
>
|
||||
{#each range(selected.cfg.maxLevel) as lvl}
|
||||
{#each range(selected.cfg.global.maxLevel) as lvl}
|
||||
<td>{getLvlValue(activity, standard, lvl)}</td>
|
||||
{/each}
|
||||
</tr>
|
||||
@@ -99,7 +99,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Body weight</th>
|
||||
{#each range(selected.cfg.maxLevel) as lvl}
|
||||
{#each range(selected.cfg.global.maxLevel) as lvl}
|
||||
<td>{lvl}</td>
|
||||
{/each}
|
||||
</tr>
|
||||
|
||||
@@ -82,7 +82,14 @@ export const app = new Elysia({ prefix: "/api" })
|
||||
}
|
||||
case Printful.Webhook.Event.PackageShipped: {
|
||||
const webflowOrderId = payload.data.order.external_id;
|
||||
await WebflowService.Orders.update(webflowOrderId, { status: "fulfilled" });
|
||||
const shipInfo = payload.data.shipment;
|
||||
|
||||
await WebflowService.Orders.update(webflowOrderId, {
|
||||
shippingTrackingURL: shipInfo.tracking_url,
|
||||
shippingTracking: shipInfo.tracking_number,
|
||||
shippingProvider: shipInfo.carrier
|
||||
});
|
||||
await WebflowService.Orders.fulfill(webflowOrderId, { sendOrderFulfilledEmail: true });
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -118,10 +125,6 @@ export const app = new Elysia({ prefix: "/api" })
|
||||
}))
|
||||
});
|
||||
|
||||
// set webflow order to pending
|
||||
webflowOrder.status = "pending";
|
||||
await WebflowService.Orders.update(webflowOrder.orderId, webflowOrder);
|
||||
|
||||
console.log("Complete");
|
||||
|
||||
break;
|
||||
|
||||
@@ -148,24 +148,19 @@ export namespace Printful {
|
||||
export interface PackageShipped extends MetaData<Event.PackageShipped, {
|
||||
shipment: {
|
||||
id: number
|
||||
status: string
|
||||
store_id: number
|
||||
carrier: string,
|
||||
service: string,
|
||||
tracking_number: string
|
||||
tracking_url: string
|
||||
created_at: string
|
||||
created: number
|
||||
ship_date: string
|
||||
shipped_at: string
|
||||
delivered_at: string
|
||||
shipped_at: number
|
||||
reshipment: boolean
|
||||
}
|
||||
order: {
|
||||
id: number
|
||||
external_id: string
|
||||
status: string
|
||||
store_id: number
|
||||
dashboard_url: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
}> { }
|
||||
|
||||
|
||||
@@ -125,20 +125,55 @@ export default class WebflowService {
|
||||
}
|
||||
|
||||
static Orders = class {
|
||||
static async update(webflowOrderId: string, webflowOrder: DeepPartial<Webflow.Orders.Order>) {
|
||||
static async getAll(opt: { status?: Webflow.Orders.Order["status"] } = {}): Promise<Webflow.Orders.Order[]> {
|
||||
// TODO: pagination
|
||||
const params = new URLSearchParams();
|
||||
if (opt.status !== undefined) {
|
||||
params.set("status", opt.status);
|
||||
}
|
||||
|
||||
const res = await fetch(`${env().API_SITES_URL}/orders?${params.toString()}`, {
|
||||
method: "GET",
|
||||
headers: { ...env().AUTH_HEADER },
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new FetchError("Failed to get all Webflow orders", res);
|
||||
}
|
||||
|
||||
const payload = await res.json();
|
||||
return payload.orders as Webflow.Orders.Order[];
|
||||
}
|
||||
|
||||
static async update(webflowOrderId: string, webflowOrderUpdate: { comment?: string, shippingProvider?: string, shippingTracking?: string, shippingTrackingURL: string }) {
|
||||
const res = await fetch(`${env().API_SITES_URL}/orders/${webflowOrderId}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...env().AUTH_HEADER
|
||||
},
|
||||
body: JSON.stringify(webflowOrder)
|
||||
body: JSON.stringify(webflowOrderUpdate)
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new FetchError("Failed to update Webflow order", res);
|
||||
}
|
||||
}
|
||||
|
||||
static async fulfill(webflowOrderId: string, opt: { sendOrderFulfilledEmail?: boolean } = {}) {
|
||||
const res = await fetch(`${env().API_SITES_URL}/orders/${webflowOrderId}/fulfill`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...env().AUTH_HEADER
|
||||
},
|
||||
body: JSON.stringify(opt)
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new FetchError("Failed to fulfill Webflow order", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Util = class {
|
||||
|
||||
+65
-61
@@ -46,71 +46,75 @@ const computedPerformances: ActivityPerformance[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const wOrders = await WebflowService.Orders.getAll();
|
||||
|
||||
console.log(wOrders);
|
||||
|
||||
// wProduct.product.fieldData.name = "Rogue Title Hoodie [White] / XS";
|
||||
//
|
||||
// WebflowService.Products.update("68e66dc4633e577c91eda727",);
|
||||
|
||||
const printfulProducts = await PrintfulService.Products.getAll();
|
||||
const webflowProducts = await WebflowService.Products.getAll();
|
||||
|
||||
for (const printfulProduct of printfulProducts) {
|
||||
if (!printfulProduct.name.includes("T-Shirt") || printfulProduct.name.includes("[White]") || printfulProduct.name.includes("[Black]")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(printfulProduct.name);
|
||||
|
||||
const fullPrintfulProduct = await PrintfulService.Products.get(printfulProduct.id);
|
||||
if (!fullPrintfulProduct) {
|
||||
console.log("Could not get full product, skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
const existingWebflowProduct = webflowProducts.find(p => fullPrintfulProduct.sync_product.name.includes(p.product.fieldData.name))
|
||||
if (!existingWebflowProduct) {
|
||||
console.log("Could not get associated webflow product, skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
const newPrintfulVariants: DeepPartial<Printful.Products.SyncVariant>[] = [];
|
||||
for (const printfulVariant of fullPrintfulProduct.sync_variants) {
|
||||
console.log(printfulVariant.name);
|
||||
const associatedWebflowSku = existingWebflowProduct.skus
|
||||
.find(sku => sku.fieldData["sku-values"]?.["color"] === SyncService.findColorInProductName(printfulVariant.name) &&
|
||||
sku.fieldData["sku-values"]?.["size"] === printfulVariant.size);
|
||||
if (associatedWebflowSku) {
|
||||
console.log('Found associated webflow sku: ' + associatedWebflowSku.fieldData.name);
|
||||
newPrintfulVariants.push({
|
||||
"id": printfulVariant.id, // printful variant id
|
||||
"external_id": String(associatedWebflowSku.id), // webflow variant id
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log("Could not get associated webflow sku");
|
||||
}
|
||||
}
|
||||
|
||||
if (!newPrintfulVariants.length) {
|
||||
console.log("No new printful variants, skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
await sleep(3000);
|
||||
try {
|
||||
await PrintfulService.Products.update(printfulProduct.id, {
|
||||
"sync_product": {
|
||||
"id": printfulProduct.id,
|
||||
"external_id": existingWebflowProduct.product.id + "-" + SyncService.findColorInProductName(printfulProduct.name)
|
||||
},
|
||||
"sync_variants": newPrintfulVariants
|
||||
});
|
||||
} catch (err) {
|
||||
if (err instanceof FetchError) {
|
||||
console.error(err.message, err.payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("DONE");
|
||||
// const printfulProducts = await PrintfulService.Products.getAll();
|
||||
// const webflowProducts = await WebflowService.Products.getAll();
|
||||
//
|
||||
// for (const printfulProduct of printfulProducts) {
|
||||
// if (!printfulProduct.name.includes("T-Shirt") || printfulProduct.name.includes("[White]") || printfulProduct.name.includes("[Black]")) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// console.log(printfulProduct.name);
|
||||
//
|
||||
// const fullPrintfulProduct = await PrintfulService.Products.get(printfulProduct.id);
|
||||
// if (!fullPrintfulProduct) {
|
||||
// console.log("Could not get full product, skipped");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// const existingWebflowProduct = webflowProducts.find(p => fullPrintfulProduct.sync_product.name.includes(p.product.fieldData.name))
|
||||
// if (!existingWebflowProduct) {
|
||||
// console.log("Could not get associated webflow product, skipped");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// const newPrintfulVariants: DeepPartial<Printful.Products.SyncVariant>[] = [];
|
||||
// for (const printfulVariant of fullPrintfulProduct.sync_variants) {
|
||||
// console.log(printfulVariant.name);
|
||||
// const associatedWebflowSku = existingWebflowProduct.skus
|
||||
// .find(sku => sku.fieldData["sku-values"]?.["color"] === SyncService.findColorInProductName(printfulVariant.name) &&
|
||||
// sku.fieldData["sku-values"]?.["size"] === printfulVariant.size);
|
||||
// if (associatedWebflowSku) {
|
||||
// console.log('Found associated webflow sku: ' + associatedWebflowSku.fieldData.name);
|
||||
// newPrintfulVariants.push({
|
||||
// "id": printfulVariant.id, // printful variant id
|
||||
// "external_id": String(associatedWebflowSku.id), // webflow variant id
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// console.log("Could not get associated webflow sku");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!newPrintfulVariants.length) {
|
||||
// console.log("No new printful variants, skipped");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// await sleep(3000);
|
||||
// try {
|
||||
// await PrintfulService.Products.update(printfulProduct.id, {
|
||||
// "sync_product": {
|
||||
// "id": printfulProduct.id,
|
||||
// "external_id": existingWebflowProduct.product.id + "-" + SyncService.findColorInProductName(printfulProduct.name)
|
||||
// },
|
||||
// "sync_variants": newPrintfulVariants
|
||||
// });
|
||||
// } catch (err) {
|
||||
// if (err instanceof FetchError) {
|
||||
// console.error(err.message, err.payload);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// console.log("DONE");
|
||||
|
||||
|
||||
// await WebflowService.Products.update(wProduct?.product.id!, wProduct!);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
let activeTab = $state("standards");
|
||||
|
||||
let input = $state({
|
||||
let inputSelected = $state({
|
||||
activity: Activity.BenchPress,
|
||||
metrics: {
|
||||
gender: Gender.Male,
|
||||
@@ -28,7 +28,7 @@
|
||||
activity,
|
||||
{
|
||||
enableGeneration: true,
|
||||
weightModfier: ".1",
|
||||
weightModifier: ".1",
|
||||
weightSkew: "0",
|
||||
ageModifier: ".1",
|
||||
},
|
||||
@@ -38,26 +38,30 @@
|
||||
});
|
||||
|
||||
const selected = $derived({
|
||||
activity: input.activity,
|
||||
activity: inputSelected.activity,
|
||||
metrics: {
|
||||
gender: input.metrics.gender,
|
||||
age: +input.metrics.age,
|
||||
weight: lbToKg(+input.metrics.weight),
|
||||
gender: inputSelected.metrics.gender,
|
||||
age: +inputSelected.metrics.age,
|
||||
weight: lbToKg(+inputSelected.metrics.weight),
|
||||
} as Metrics,
|
||||
cfg: {
|
||||
global: {
|
||||
maxLevel: +input.cfg.global.maxLevel,
|
||||
maxLevel: +inputSelected.cfg.global.maxLevel,
|
||||
},
|
||||
activity: Object.fromEntries(
|
||||
Object.values(Activity).map((activity) => [
|
||||
activity,
|
||||
{
|
||||
weightModifier:
|
||||
+input.cfg.activity[activity].weightModfier,
|
||||
weightSkew: +input.cfg.activity[activity].weightSkew,
|
||||
ageModifier: +input.cfg.activity[activity].ageModifier,
|
||||
+inputSelected.cfg.activity[activity]
|
||||
.weightModifier,
|
||||
weightSkew:
|
||||
+inputSelected.cfg.activity[activity].weightSkew,
|
||||
ageModifier:
|
||||
+inputSelected.cfg.activity[activity].ageModifier,
|
||||
disableGeneration:
|
||||
!input.cfg.activity[activity].enableGeneration,
|
||||
!inputSelected.cfg.activity[activity]
|
||||
.enableGeneration,
|
||||
},
|
||||
]),
|
||||
),
|
||||
@@ -70,16 +74,16 @@
|
||||
|
||||
$effect(() => {
|
||||
console.log(selected);
|
||||
if (!input.metrics.age) input.metrics.weight = "";
|
||||
if (!inputSelected.metrics.age) inputSelected.metrics.weight = "";
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
const savedParameters = localStorage.getItem("parameters");
|
||||
if (savedParameters) input = JSON.parse(savedParameters);
|
||||
if (savedParameters) inputSelected = JSON.parse(savedParameters);
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
localStorage.setItem("parameters", JSON.stringify(input));
|
||||
localStorage.setItem("parameters", JSON.stringify(inputSelected));
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -102,7 +106,7 @@
|
||||
min="1"
|
||||
max="100"
|
||||
placeholder="5"
|
||||
bind:value={input.cfg.global.maxLevel}
|
||||
bind:value={inputSelected.cfg.global.maxLevel}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
@@ -118,7 +122,7 @@
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={
|
||||
input.cfg.activity[selected.activity]
|
||||
inputSelected.cfg.activity[selected.activity]
|
||||
.enableGeneration
|
||||
}
|
||||
class="toggle toggle-lg m-auto"
|
||||
@@ -134,8 +138,8 @@
|
||||
step=".05"
|
||||
placeholder=".1"
|
||||
bind:value={
|
||||
input.cfg.activity[selected.activity]
|
||||
.weightModfier
|
||||
inputSelected.cfg.activity[selected.activity]
|
||||
.weightModifier
|
||||
}
|
||||
disabled={selected.cfg.activity[selected.activity]
|
||||
.disableGeneration}
|
||||
@@ -151,7 +155,8 @@
|
||||
step=".05"
|
||||
placeholder=".1"
|
||||
bind:value={
|
||||
input.cfg.activity[selected.activity].weightSkew
|
||||
inputSelected.cfg.activity[selected.activity]
|
||||
.weightSkew
|
||||
}
|
||||
disabled={selected.cfg.activity[selected.activity]
|
||||
.disableGeneration}
|
||||
@@ -167,7 +172,7 @@
|
||||
step=".05"
|
||||
placeholder=".1"
|
||||
bind:value={
|
||||
input.cfg.activity[selected.activity]
|
||||
inputSelected.cfg.activity[selected.activity]
|
||||
.ageModifier
|
||||
}
|
||||
disabled={selected.cfg.activity[selected.activity]
|
||||
@@ -190,7 +195,7 @@
|
||||
<select
|
||||
class="select w-full"
|
||||
name="activities"
|
||||
bind:value={input.activity}
|
||||
bind:value={inputSelected.activity}
|
||||
>
|
||||
{#each Object.values(Activity) as activity}
|
||||
<option value={activity}>
|
||||
@@ -206,7 +211,7 @@
|
||||
<select
|
||||
class="select w-full"
|
||||
name="genders"
|
||||
bind:value={input.metrics.gender}
|
||||
bind:value={inputSelected.metrics.gender}
|
||||
>
|
||||
{#each Object.values(Gender) as gender}
|
||||
<option value={gender}>{gender}</option>
|
||||
@@ -222,7 +227,7 @@
|
||||
min="0"
|
||||
max="100"
|
||||
placeholder="18"
|
||||
bind:value={input.metrics.age}
|
||||
bind:value={inputSelected.metrics.age}
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -236,7 +241,7 @@
|
||||
placeholder={selected.metrics.age
|
||||
? "170"
|
||||
: "Requires age"}
|
||||
bind:value={input.metrics.weight}
|
||||
bind:value={inputSelected.metrics.weight}
|
||||
disabled={!selected.metrics.age}
|
||||
/>
|
||||
</label>
|
||||
|
||||
Reference in New Issue
Block a user