diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte index 34de1f0..d7475dd 100644 --- a/src/lib/components/app-sidebar.svelte +++ b/src/lib/components/app-sidebar.svelte @@ -12,7 +12,6 @@ CupSodaIcon, Shield, FileSpreadsheet, - DollarSign, MonitorSmartphone, PlusCircle, ImageUp, @@ -136,12 +135,6 @@ url: '/departments', icon: FileSpreadsheet, requirePerm: 'document.write.*' - }, - { - title: 'PriceSlot', - url: '/departments', - icon: DollarSign, - requirePerm: 'document.write.*' } ] } @@ -235,7 +228,7 @@ onclick={(e) => { if (nav.title === 'Sheet') { e.preventDefault(); - referenceFromPage.set(sub.title === 'PriceSlot' ? 'priceslot' : 'sheet'); + referenceFromPage.set('sheet'); goto(sub.url); } }} diff --git a/src/lib/core/handlers/messageHandler.ts b/src/lib/core/handlers/messageHandler.ts index 61cd6a3..b875029 100644 --- a/src/lib/core/handlers/messageHandler.ts +++ b/src/lib/core/handlers/messageHandler.ts @@ -395,59 +395,59 @@ const handlers: Record void> = { lastRequestSheetPrice.set(lastRequestPriceInstance); }, - // raw_stream: (p) => { - // let streamRawInstance = get(streamingRawData); - // let sub_type = p.sub_type; - // let request_id = p.request_id; - // let size_per_chunk = p.size_per_chunk; - // let total_chunks = p.total_chunks; - // let idx = p.idx; + raw_stream: (p) => { + let streamRawInstance = get(streamingRawData); + let sub_type = p.sub_type; + let request_id = p.request_id; + let size_per_chunk = p.size_per_chunk; + let total_chunks = p.total_chunks; + let idx = p.idx; - // switch (sub_type) { - // case 'price': - // streamingRawMeta.set({ - // id: request_id, - // total_size: total_chunks, - // chunk_size: size_per_chunk, - // progress: 0 - // }); - // break; - // case 'chunk_price': - // streamingRawMeta.set({ - // id: request_id, - // total_size: total_chunks, - // chunk_size: size_per_chunk, - // progress: idx - // }); + switch (sub_type) { + case 'price': + streamingRawMeta.set({ + id: request_id, + total_size: total_chunks, + chunk_size: size_per_chunk, + progress: 0 + }); + break; + case 'chunk_price': + streamingRawMeta.set({ + id: request_id, + total_size: total_chunks, + chunk_size: size_per_chunk, + progress: idx + }); - // let raw_payload = p.raw ?? ''; - // streamRawInstance[request_id] += raw_payload; - // streamingRawData.set(streamRawInstance); + let raw_payload = p.raw ?? ''; + streamRawInstance[request_id] += raw_payload; + streamingRawData.set(streamRawInstance); - // break; - // case 'end_price': - // let lastRequestPriceInstance = get(lastRequestSheetPrice); - // let country = lastRequestPriceInstance[request_id]; + break; + case 'end_price': + let lastRequestPriceInstance = get(lastRequestSheetPrice); + let country = lastRequestPriceInstance[request_id]; - // try { - // let raw_payload = JSON.parse(streamRawInstance[request_id]); - // let ref_from_raw = raw_payload.payload.ref ?? ''; - // let from_service_raw = raw_payload.payload.from ?? ''; - // let parsed_payload = raw_payload.payload ?? ''; + try { + let raw_payload = JSON.parse(streamRawInstance[request_id]); + let ref_from_raw = raw_payload.payload.ref ?? ''; + let from_service_raw = raw_payload.payload.from ?? ''; + let parsed_payload = raw_payload.payload ?? ''; - // if (from_service_raw == 'sheet-service') { - // handleSheetResponseFromNoti(parsed_payload, ref_from_raw, country); - // delete streamRawInstance[request_id]; - // streamingRawData.set(streamRawInstance); - // } - // } catch (e) { - // console.log(`end price process error: ${e}`); - // } + if (from_service_raw == 'sheet-service') { + handleSheetResponseFromNoti(parsed_payload, ref_from_raw, country); + delete streamRawInstance[request_id]; + streamingRawData.set(streamRawInstance); + } + } catch (e) { + console.log(`end price process error: ${e}`); + } - // break; - // default: - // } - // }, + break; + default: + } + }, heartbeat: (p) => { socketConnectionOfflineCount.set(0); socketAlreadySendHeartbeat.set(0); @@ -486,12 +486,12 @@ export function handleIncomingMessages(raw: string) { } // raw streaming type - // if (msg.type.startsWith('raw_stream')) { - // // convert - // let sub_type = msg.type.replace('raw_stream_', ''); - // msg.payload.sub_type = sub_type; - // msg.type = 'raw_stream'; - // } + if (msg.type.startsWith('raw_stream')) { + // convert + let sub_type = msg.type.replace('raw_stream_', ''); + msg.payload.sub_type = sub_type; + msg.type = 'raw_stream'; + } handlers[msg.type]?.(msg.payload); } diff --git a/src/lib/core/services/sheetService.ts b/src/lib/core/services/sheetService.ts index 8fb6c39..2e15f35 100644 --- a/src/lib/core/services/sheetService.ts +++ b/src/lib/core/services/sheetService.ts @@ -18,29 +18,6 @@ export function requestCatalogs(country: string): boolean { }); } -export function requestPriceSlots(country: string): boolean { - return sendCommandRequest('sheet', { - country: country, - param: 'priceslot' - }); -} - -export function updatePriceSlot( - country: string, - content: { - slot: number; - name: string; - description: string; - products: { product_code: string; price: number | null; row_index?: number }[]; - } -): boolean { - return sendCommandRequest('sheet', { - country: country, - content: content, - param: 'update/priceslot' - }); -} - export function enterRoom(country: string, catalog: string): boolean { return sendCommandRequest('sheet', { country: country, diff --git a/src/lib/core/stores/sheetStore.ts b/src/lib/core/stores/sheetStore.ts index eb2d626..5a2e0dc 100644 --- a/src/lib/core/stores/sheetStore.ts +++ b/src/lib/core/stores/sheetStore.ts @@ -17,24 +17,6 @@ export interface CatalogsResponse { export const sheetCatalogs = writable([]); export const sheetCatalogsLoading = writable(false); -export interface PriceSlotProduct { - product_code: string; - name: string; - price: number | null; - row_index?: number; -} - -export interface PriceSlot { - slot: number; - name: string; - description: string; - products: PriceSlotProduct[]; -} - -export const priceSlots = writable>({}); -export const priceSlotsLoading = writable(false); -export const priceSlotsError = writable(null); - export const countryPrimaryLanguageMap: Record = { THAI: 'Thai', tha: 'Thai', diff --git a/src/routes/(authed)/departments/+page.svelte b/src/routes/(authed)/departments/+page.svelte index 77ce3d9..e2e80f6 100644 --- a/src/routes/(authed)/departments/+page.svelte +++ b/src/routes/(authed)/departments/+page.svelte @@ -25,9 +25,7 @@ console.log(get(departmentStore)); departmentStore.set(cnt); - if (refPage === 'priceslot') { - await goto(`/sheet/priceslot/${cnt}`); - } else if (refPage === 'sheet') { + if (refPage === 'sheet') { await goto(`/sheet/overview/${cnt}`); } else { await goto('/recipe/overview'); diff --git a/src/routes/(authed)/recipe/material/+page.svelte b/src/routes/(authed)/recipe/material/+page.svelte index e7beba8..e69de29 100644 --- a/src/routes/(authed)/recipe/material/+page.svelte +++ b/src/routes/(authed)/recipe/material/+page.svelte @@ -1,842 +0,0 @@ - - -
-
-
-
-

- Android Recipe -

-

Material Setting

- - {#if loadedRecipePath} -

Loaded: {loadedRecipePath}

- {/if} -
- -
- -
-
-
- -
-
-
-
Total materials
-
{materials.length}
-
-
-
-
Active materials
-
{activeMaterialCount}
-
-
-
-
Channels in use
-
{channelSummary.length}
-
-
- - - - - {existingMaterial ? 'Edit Material' : 'Add Material'} - - Create or update one MaterialSetting entry. The JSON preview shows the payload - before saving to Android. - - - -
- - - {existingMaterial ? 'Edit Material' : 'Add Material'} - - - {#if existingMaterial} -
- Material ID {form.id} already exists. Saving will update this MaterialSetting. -
- {/if} - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
- - -

- Examples: refill=$bag,sum=$gram,rec=$gram, - refill=$L,sum=$ml,rec=$ml -

-
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - - - - -
- -
- - -
- -
- - - -
-
-
- - - - Preview JSON - - Payload that will be upserted into MaterialSetting. - - - -
{previewJson}
-
-
-
-
-
- - - -
-
- Existing Materials - - Use Edit to update a material, or Delete to remove it after confirmation. - -
- -
-
- -
- -
- {#each channelSummary as channel} - - {channel.label}: {channel.count} - - {/each} -
-
-
- {#if loading} -
- - Loading materials from Android... -
- {:else if !devRecipe} -
Connect and load recipe first.
- {:else if filteredMaterials.length === 0} -
No materials found.
- {:else} - -
- {#each filteredMaterials as material} -
- {material.id} - {material.materialName || '-'} - {material.materialOtherName || '-'} - {material.pathOtherName || '-'} - - {(material.isUse as boolean) !== false ? 'Use' : 'Not use'} - -
- - -
-
- {/each} -
- {/if} -
-
-
- - - - - Delete Material? - - This will remove the material from MaterialSetting in the Android recipe JSON. - - - - {#if pendingDeleteMaterial} -
-
Material
-
{pendingDeleteMaterial.id}
-
- {pendingDeleteMaterial.materialName || - pendingDeleteMaterial.materialOtherName || - 'Unnamed'} -
-
- {/if} - -
- - -
-
-
-
diff --git a/src/routes/(authed)/recipe/topping/+page.svelte b/src/routes/(authed)/recipe/topping/+page.svelte index c0e2a25..e69de29 100644 --- a/src/routes/(authed)/recipe/topping/+page.svelte +++ b/src/routes/(authed)/recipe/topping/+page.svelte @@ -1,1071 +0,0 @@ - - -
-
-
-
-

- Android Recipe -

-

Topping

- - {#if loadedRecipePath} -

Loaded: {loadedRecipePath}

- {/if} -
- - -
-
- -
-
-
-
ToppingList
-
{toppingList.length}
-
-
-
-
Active list items
-
{activeListCount}
-
-
-
-
ToppingGroup
-
{toppingGroups.length}
-
-
- - - -
-
- {activeTab === 'list' ? 'Topping List' : 'Topping Group'} - - Switch between list items and groups. Edit/Delete actions are explicit per row. - -
-
- - -
-
-
- -
- - {#if activeTab === 'list'} - - {:else} - - {/if} -
- -
- {#if loading} -
- - Loading toppings from Android... -
- {:else if !devRecipe} -
Connect and load recipe first.
- {:else if activeTab === 'list'} - {#if filteredToppingList.length === 0} -
No topping list items found.
- {:else} - -
- {#each filteredToppingList as item} -
- {item.id} - {item.name || '-'} - {item.otherName || '-'} - - {(item.isUse as boolean) !== false ? 'Use' : 'Not use'} - -
- - -
-
- {/each} -
- {/if} - {:else if filteredToppingGroups.length === 0} -
No topping groups found.
- {:else} - -
- {#each filteredToppingGroups as group} -
- {group.groupID} - {group.name || '-'} - {group.otherName || '-'} - {group.idInGroup || '-'} - - {(group.inUse as boolean) !== false ? 'Use' : 'Not use'} - -
- - -
-
- {/each} -
- {/if} -
-
-
- - - - - {existingListItem ? 'Edit Topping' : 'Add Topping'} - Manage one item inside ToppingList. - - -
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - - -
-
-
-
Recipe steps
-
- Some toppings need multiple recipe JSON steps, such as sugar plus stir. -
-
- -
- -
- {#each listForm.recipeSteps as step, index} -
-
-
Step {index + 1}
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
- {/each} -
-
- -
- - -
-
-
- - - - Preview JSON - - -
{JSON.stringify(
-								listPreview,
-								null,
-								2
-							)}
-
-
-
-
-
- - - - - {existingGroup ? 'Edit Topping Group' : 'Add Topping Group'} - Manage one group inside ToppingGroup. - - -
- - -
-
- - -
-
- - -
- -
- -
-
- - -
-
- - -
-
- -
- - -
- -
- - -

Comma-separated `ToppingList.id` values.

-
- -
- - -
-
-
- - - - Preview JSON - - -
{JSON.stringify(
-								groupPreview,
-								null,
-								2
-							)}
-
-
-
-
-
- - - - - Delete Topping? - This will remove the selected entry from Android recipe JSON. - - - {#if pendingDelete} -
-
- {pendingDelete.type === 'list' ? 'ToppingList' : 'ToppingGroup'} -
-
- {pendingDelete.type === 'list' - ? (pendingDelete.item as ToppingListItem).id - : (pendingDelete.item as ToppingGroup).groupID} -
-
- {pendingDelete.item.name || pendingDelete.item.otherName || 'Unnamed'} -
-
- {/if} - -
- - -
-
-
-
diff --git a/src/routes/(authed)/sheet/priceslot/[country]/+page.svelte b/src/routes/(authed)/sheet/priceslot/[country]/+page.svelte deleted file mode 100644 index 86a2542..0000000 --- a/src/routes/(authed)/sheet/priceslot/[country]/+page.svelte +++ /dev/null @@ -1,586 +0,0 @@ - - -
-
-
-
-

- PriceSlot [ {selectedCountry.toUpperCase()} ] -

-

- Edit sheet PriceSlot names, descriptions, and product prices. -

-
-
- {#if enabledCountries.length > 0} - { - if (v) { - selectedCountry = v; - goto(`/sheet/priceslot/${v}`); - } - }} - > - - {selectedCountry.toUpperCase()} - - - {#each enabledCountries as country} - - {country.toUpperCase()} - - {/each} - - - {/if} - - -
-
- -
- {#each slots as slot} - - {/each} -
- -
-
-
-
-

PriceSlot{selectedSlot}

- - {hasChanges ? `${changedCount} changes` : 'No changes'} - -
- -
- -
- - updateSlotField('name', event.currentTarget.value)} - /> -
- -
- - updateSlotField('description', event.currentTarget.value)} - /> -
- -
- - - -
-
-
- -
-
-
- -
- - -
-
-

- Showing {filteredProducts.length} of {currentSlot.products.length} products -

-
- -
- - - - ProductCode - ProductName [{selectedCountryLanguage}] - ProductNameEng - Price - - - - {#each filteredProducts as product (product.product_code)} - {@const productNames = getProductNames(product)} - - - {product.product_code} - - {productNames.local} - {productNames.english} - - - updateProductPrice(product.product_code, event.currentTarget.value)} - /> - - - {/each} - {#if filteredProducts.length === 0} - - - No product code found. - - - {/if} - - -
-
-
-
- - - - - Create PriceSlot - - Choose how to adjust base prices before creating a new PriceSlot. - - - -
- - -
-
- - { - if (v) adjustmentMode = v as AdjustmentMode; - applyCreateTemplate(); - }} - > - - {adjustmentModeLabels[adjustmentMode]} - - - Increase by Percentage (%) - Increase by Fixed Amount - Decrease by Percentage (%) - Decrease by Fixed Amount - - -
- -
- - { - adjustmentValue = Number(event.currentTarget.value); - applyCreateTemplate(); - }} - /> -
- -
- - (createName = event.currentTarget.value)} - /> -
- -
- - (createDescription = event.currentTarget.value)} - /> -
-
-
- - - - - -
-
diff --git a/src/routes/(authed)/tools/adv-upload/+page.svelte b/src/routes/(authed)/tools/adv-upload/+page.svelte index 1735f59..ec63447 100644 --- a/src/routes/(authed)/tools/adv-upload/+page.svelte +++ b/src/routes/(authed)/tools/adv-upload/+page.svelte @@ -28,8 +28,8 @@ // pushes the selected .mp4 (from the browser), then // `ls -l > sync_1.file` on the machine, pulls it, uploads it. // ⚠️ FULL REPLACE — requires ADB; select the COMPLETE adv set. - const MANIFEST_MODE: 'ftp_listdir' | 'machine' = 'ftp_listdir'; - //const MANIFEST_MODE: 'ftp_listdir' | 'machine' = 'machine'; + //const MANIFEST_MODE: 'ftp_listdir' | 'machine' = 'ftp_listdir'; + const MANIFEST_MODE: 'ftp_listdir' | 'machine' = 'machine'; // ───────────────────────────────────────────────────────────────────────── // adv folder on the machine. Domestic Thailand uses the flat folder; every