Skip to content

Commit 17003b0

Browse files
committed
feature: visibility for disabled items in admin menu, better disabled item handling
1 parent f0b4f2a commit 17003b0

File tree

5 files changed

+67
-48
lines changed

5 files changed

+67
-48
lines changed

backend/controllers/api/v1/item.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func CreateItem(c *gin.Context) {
8787
// @Router /items [get]
8888
func FindItems(c *gin.Context) {
8989
var items []models.Item
90-
models.DB.Order("created_at ASC").Where("is_active = ?", true).Where("deleted_at IS NULL").Find(&items)
90+
models.DB.Order("created_at ASC").Where("deleted_at IS NULL").Find(&items)
9191

9292
c.Header("Content-Type", "application/json")
9393
c.JSON(http.StatusOK, gin.H{"data": items})

backend/controllers/api/v1/purchase.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ func CreatePurchase(c *gin.Context) {
6969
}
7070

7171
if input.Amount != 0 && len(input.Items) != 0 {
72-
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "only one of 'items' and 'amount' can be specified"})
72+
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "Only one of 'items' and 'amount' can be specified"})
7373
return
7474
}
7575

7676
if input.Amount != 0 && input.PaymentType == models.PaymentTypeBalance {
77-
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "balance payment type cannot be used with amount"})
77+
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "Balance payment type cannot be used with amount"})
7878
return
7979
}
8080

@@ -85,6 +85,10 @@ func CreatePurchase(c *gin.Context) {
8585

8686
for _, v := range input.Items {
8787
item := FindItemById(v.ItemId)
88+
if item.IsActive != nil && *item.IsActive == false {
89+
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "Attempted to purchase inactive item"})
90+
return
91+
}
8892
finalCost += item.Price * v.Amount
8993
returnedItemsArray = append(returnedItemsArray, models.PurchaseItem{ItemId: v.ItemId, ProductName: item.ProductName, ProductVariant: item.ProductVariant, Price: item.Price, Amount: v.Amount})
9094
if v.Amount > 1 {

frontend/app/items/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,13 @@ export default function ItemsPage() {
4848
return <div className="flex justify-center mt-20">Loading...</div>;
4949
}
5050

51+
// Filter to show only active items
52+
const activeItems = items.filter((item) => item.is_active === true);
53+
5154
return (
5255
<div className="p-4">
5356
<BarcodeSearchInput items={items} visible={false} />
54-
<ItemCards items={items} onItemClick={addItem} />
57+
<ItemCards items={activeItems} onItemClick={addItem} />
5558
</div>
5659
);
5760
}

frontend/components/item-cards.tsx

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,61 @@ export default function ItemCards({ items, onItemClick }: ItemCardsProps) {
2525

2626
return (
2727
<div className="w-full px-4 pb-4 gap-4 flex flex-wrap justify-center">
28-
{items.map((item) => (
29-
<div key={item.id} className="w-48">
30-
<Button
31-
variant="ghost"
32-
className="p-0 w-full min-h-68"
33-
onClick={() => handleClick(item)}
34-
>
35-
<Card className="w-full h-full">
36-
<CardContent className="pt-2 px-4 pb-2 h-full flex flex-col items-center justify-center">
37-
<div className="aspect-square rounded-md overflow-hidden flex-shrink-0 w-full">
38-
{item.image ? (
39-
<Image
40-
src={item.image}
41-
alt={
42-
item.variant
43-
? `${item.name} ${item.variant}`
44-
: item.name
45-
}
46-
className="object-contain h-full w-full"
47-
width={100}
48-
height={100}
49-
/>
50-
) : (
51-
<div className="flex items-center justify-center h-full w-full">
52-
<span className="text-gray-400 text-[4rem] font-bold">
53-
?
54-
</span>
55-
</div>
56-
)}
57-
</div>
58-
<div className="flex flex-col items-center justify-center text-center mt-3 flex-grow w-full">
59-
<CardTitle className="mt-2 text-center text-base leading-normal w-full whitespace-normal break-words">
60-
{item.variant ? `${item.name} ${item.variant}` : item.name}
61-
</CardTitle>
62-
<span className="text-xs text-gray-500 mt-1">
63-
{(item.price / 100).toFixed(2)}€ / {item.volume}ml
64-
</span>
65-
</div>
66-
</CardContent>
67-
</Card>
68-
</Button>
69-
</div>
70-
))}
28+
{items.map((item) => {
29+
const isInactive =
30+
item.is_active === false ||
31+
item.is_active === null ||
32+
item.is_active === undefined;
33+
return (
34+
<div key={item.id} className="w-48">
35+
<Button
36+
variant="ghost"
37+
className="p-0 w-full min-h-68"
38+
onClick={() => handleClick(item)}
39+
>
40+
<Card
41+
className={`w-full h-full ${
42+
isInactive ? "opacity-50 bg-gray-100 dark:bg-gray-800" : ""
43+
}`}
44+
>
45+
<CardContent className="pt-2 px-4 pb-2 h-full flex flex-col items-center justify-center">
46+
<div className="aspect-square rounded-md overflow-hidden flex-shrink-0 w-full">
47+
{item.image ? (
48+
<Image
49+
src={item.image}
50+
alt={
51+
item.variant
52+
? `${item.name} ${item.variant}`
53+
: item.name
54+
}
55+
className="object-contain h-full w-full"
56+
width={100}
57+
height={100}
58+
/>
59+
) : (
60+
<div className="flex items-center justify-center h-full w-full">
61+
<span className="text-gray-400 text-[4rem] font-bold">
62+
?
63+
</span>
64+
</div>
65+
)}
66+
</div>
67+
<div className="flex flex-col items-center justify-center text-center mt-3 flex-grow w-full">
68+
<CardTitle className="mt-2 text-center text-base leading-normal w-full whitespace-normal break-words">
69+
{item.variant
70+
? `${item.name} ${item.variant}`
71+
: item.name}
72+
</CardTitle>
73+
<span className="text-xs text-gray-500 mt-1">
74+
{(item.price / 100).toFixed(2)}€ / {item.volume}ml
75+
</span>
76+
</div>
77+
</CardContent>
78+
</Card>
79+
</Button>
80+
</div>
81+
);
82+
})}
7183
</div>
7284
);
7385
}

frontend/types/item.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export type Item = {
88
amount?: number;
99
barcodes?: string[];
1010
nutrition_info?: NutritionInfo[];
11-
is_active: boolean;
11+
is_active?: boolean;
1212
};
1313

1414
type NutritionInfo = {

0 commit comments

Comments
 (0)