ProductBarcode: apply linting and fixes on frontend

This commit is contained in:
Crumb Owl
2025-07-07 13:07:14 +00:00
parent 68b6d58ab4
commit 18149a5c9a
5 changed files with 91 additions and 97 deletions

View File

@@ -15,13 +15,14 @@
</div>
<div
v-if="detectedBarcode"
class="border-accent-foreground bg-accent text-accent-foreground mb-5 flex flex-col items-center gap-2 rounded-md border p-4"
class="mb-5 flex flex-col items-center gap-2 rounded-md border border-accent-foreground bg-accent p-4 text-accent-foreground"
role="alert"
>
<div class="flex">
<MdiBarcode class="text-default mr-2" />
<MdiBarcode class="mr-2" />
<span class="flex-1 text-center text-sm font-medium">
{{ detectedBarcodeType }} {{ $t("scanner.barcode_detected_message") }}: <strong>{{ detectedBarcode }}</strong>
{{ detectedBarcodeType }} {{ $t("scanner.barcode_detected_message") }}:
<strong>{{ detectedBarcode }}</strong>
</span>
</div>
@@ -74,7 +75,6 @@
const errorMessage = ref<string | null>(null);
const detectedBarcode = ref<string>("");
const detectedBarcodeType = ref<string>("");
const api = useUserApi();
const handleError = (error: unknown) => {
console.error("Scanner error:", error);
@@ -170,7 +170,7 @@
case BarcodeFormat.UPC_EAN_EXTENSION:
console.info("Barcode detected");
detectedBarcode.value = result.getText();
detectedBarcodeType.value = BarcodeFormat[bcfmt].replaceAll("_","-");
detectedBarcodeType.value = BarcodeFormat[bcfmt].replaceAll("_", "-");
break;
default:
@@ -194,4 +194,3 @@
stopScanner();
});
</script>

View File

@@ -1,13 +1,22 @@
<template>
<Dialog dialog-id="product-import">
<DialogContent :class="'w-full md:max-w-xl lg:max-w-4xl'" >
<DialogContent :class="'w-full md:max-w-xl lg:max-w-4xl'">
<DialogHeader>
<DialogTitle>{{ $t("components.item.product_import.title") }}</DialogTitle>
</DialogHeader>
<div class="flex items-center space-x-4">
<FormTextField :disabled=searching class="w-[30%]" :modelValue="barcode" :label="$t('components.item.product_import.barcode')" />
<Button :variant="searching ? 'destructive' : 'default'" @click="retrieveProductInfo(barcode)" style="margin-top: auto">
<FormTextField
:disabled="searching"
class="w-[30%]"
:model-value="barcode"
:label="$t('components.item.product_import.barcode')"
/>
<Button
:variant="searching ? 'destructive' : 'default'"
style="margin-top: auto"
@click="retrieveProductInfo(barcode)"
>
<div class="relative mx-2">
<div class="absolute inset-0 flex items-center justify-center">
<MdiBarcode class="size-5 group-hover:hidden" />
@@ -46,15 +55,18 @@
<TableRow
v-for="(p, index) in products"
:key="index"
class='cursor-pointer'
class="cursor-pointer"
:class="{ selected: selectedRow === index }"
@click="selectProduct(index)">
<TableCell v-for="h in headers"
@click="selectProduct(index)"
>
<TableCell
v-for="h in headers"
:key="h.value"
:class="{
'text-center': h.align === 'center',
'text-left': h.align === 'left',
}">
}"
>
<template v-if="h.type === 'name'">
<div class="flex items-center space-x-4">
<img :src="p.imageBase64" class="w-16 rounded object-fill shadow-sm" alt="Product's photo" />
@@ -81,20 +93,19 @@
</template>
<script setup lang="ts">
import { Button, ButtonGroup } from "~/components/ui/button";
import { Button } from "~/components/ui/button";
import type { BarcodeProduct } from "~~/lib/api/types/data-contracts";
import { useDialog } from "~/components/ui/dialog-provider";
import MdiBarcode from "~icons/mdi/barcode";
import type { TableData } from "~/components/Item/View/Table.types";
const { openDialog, activeDialog, closeDialog } = useDialog();
const { openDialog, activeDialog } = useDialog();
const searching = ref(false);
const barcode = ref<string>("");
const products = ref<BarcodeProduct[] | null>(null);
const selectedRow = ref(-1);
import type { ItemSummary } from "~~/lib/api/types/data-contracts";
type BarcodeTableHeader = {
text: string;
value: string;
@@ -109,9 +120,9 @@
align: "left",
type: "name",
},
{ text: "items.manufacturer", value: "manufacturer", align: "center"},
{ text: "items.model_number", value: "modelNumber", align: "center"},
{ text: "DB source", value: "search_engine_name", align: "center"},
{ text: "items.manufacturer", value: "manufacturer", align: "center" },
{ text: "items.model_number", value: "modelNumber", align: "center" },
{ text: "DB source", value: "search_engine_name", align: "center" },
] satisfies BarcodeTableHeader[];
// Need for later filtering
@@ -123,21 +134,16 @@
if (active && active.id === "product-import") {
selectedRow.value = -1;
if(active.params)
{
if (active.params) {
// Reset if the barcode is different
if(active.params != barcode.value)
{
if (active.params !== barcode.value) {
barcode.value = active.params;
retrieveProductInfo(barcode.value).then(() =>
{
retrieveProductInfo(barcode.value).then(() => {
console.log("Processing finished");
});
}
}
else
{
} else {
barcode.value = "";
products.value = null;
}
@@ -147,10 +153,9 @@
const api = useUserApi();
async function createItem(close = true) {
if (products !== null)
{
var p = products.value![selectedRow.value];
function createItem() {
if (products !== null) {
const p = products.value![selectedRow.value];
openDialog("create-item", p);
}
}
@@ -160,23 +165,19 @@
searching.value = true;
if (!barcode || barcode.trim().length === 0) {
console.error('Invalid barcode provided');
console.error("Invalid barcode provided");
return;
}
try {
const result = await api.products.searchFromBarcode(barcode.trim());
if(result.error)
{
console.error('API Error:', result.error);
return;
}
else
{
if (result.error) {
console.error("API Error:", result.error);
} else {
products.value = result.data;
}
} catch (error) {
console.error('Failed to retrieve product info:', error);
console.error("Failed to retrieve product info:", error);
} finally {
searching.value = false;
}
@@ -197,26 +198,22 @@
function selectProduct(index: number) {
// Unselect if already selected
if(selectedRow.value == index)
{
if (selectedRow.value === index) {
selectedRow.value = -1;
return;
}
selectedRow.value = index;
}
</script>
<style>
tr.selected {
tr.selected {
background-color: hsl(var(--primary));
color: hsl(var(--background));
}
}
tr:hover.selected {
tr:hover.selected {
background-color: hsl(var(--primary));
}
}
</style>

View File

@@ -10,7 +10,7 @@
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{{ $t('components.item.create_modal.product_tooltip_input_barcode') }}</p>
<p>{{ $t("components.item.create_modal.product_tooltip_input_barcode") }}</p>
</TooltipContent>
</Tooltip>
<Tooltip>
@@ -20,17 +20,17 @@
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{{ $t('components.item.create_modal.product_tooltip_scan_barcode') }}</p>
<p>{{ $t("components.item.create_modal.product_tooltip_scan_barcode") }}</p>
</TooltipContent>
</Tooltip>
</ButtonGroup>
</TooltipProvider >
<div class= "items-center justify-center flex mx-2">
{{ $t('components.item.create_modal.product_autofill') }}
</TooltipProvider>
<div class="mx-2 flex items-center justify-center">
{{ $t("components.item.create_modal.product_autofill") }}
</div>
</div>
<div class=" border-t" />
<div class="border-t" />
<form class="flex flex-col gap-2" @submit.prevent="create()">
<LocationSelector v-model="form.location" />
@@ -345,18 +345,16 @@
}
}
if(active.params)
{
if (active.params) {
form.name = active.params.item.name;
form.description = active.params.item.description;
if(active.params.imageURL)
{
if (active.params.imageURL) {
form.photos.push({
photoName: "product_view.jpg",
fileBase64: active.params.imageBase64,
primary: form.photos.length === 0,
file: dataURLtoFile(active.params.imageBase64 ,"product_view.jpg")
file: dataURLtoFile(active.params.imageBase64, "product_view.jpg"),
});
}
}
@@ -517,13 +515,13 @@
}
}
async function openQrScannerPage() {
function openQrScannerPage() {
closeDialog("create-item");
openDialog("scanner")
openDialog("scanner");
}
async function openBarcodeDialog() {
function openBarcodeDialog() {
closeDialog("create-item");
openDialog("product-import")
openDialog("product-import");
}
</script>

View File

@@ -1,5 +1,5 @@
import { BaseAPI, route } from "../base";
import type { ActionAmountResult, ItemCreate } from "../types/data-contracts";
import type { ActionAmountResult } from "../types/data-contracts";
export class ActionsAPI extends BaseAPI {
ensureAssetIDs() {