Skip to content

Commit 0b38e19

Browse files
author
alexandrosnt
committed
v0.1.8: Inventory quantity display/edit, pagination, iPhone safe area
1 parent 091fe89 commit 0b38e19

6 files changed

Lines changed: 74 additions & 3 deletions

File tree

src/app.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ body {
3838
overflow: hidden;
3939
display: flex;
4040
flex-direction: column;
41+
padding-top: env(safe-area-inset-top, 0px);
4142
}
4243

4344
@keyframes gradientBG {

src/lib/components/ItemDetailSheet.svelte

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
let editCategoryId = $state(0);
3030
let editSubcategoryId = $state(0);
3131
let editPrice = $state('');
32+
let editQuantity = $state(1);
3233
let editNotes = $state('');
3334
/** @type {Category[]} */
3435
let categories = $state([]);
@@ -148,6 +149,7 @@
148149
editCategoryId = displayItem.category_id;
149150
editSubcategoryId = displayItem.subcategory_id ?? 0;
150151
editPrice = displayItem.purchase_price != null ? String(displayItem.purchase_price) : '';
152+
editQuantity = displayItem.quantity ?? 1;
151153
editNotes = displayItem.notes ?? '';
152154
categories = await getCategories();
153155
if (displayItem.category_id) {
@@ -173,6 +175,7 @@
173175
category_id: editCategoryId,
174176
subcategory_id: editSubcategoryId > 0 ? editSubcategoryId : null,
175177
purchase_price: editPrice ? Number(editPrice) : null,
178+
quantity: editQuantity > 0 ? editQuantity : 1,
176179
notes: editNotes || null
177180
});
178181
triggerRefresh();
@@ -300,6 +303,17 @@
300303
/>
301304
</div>
302305
306+
<div class="form-group">
307+
<label for="edit-quantity">{t.addModal.quantity}</label>
308+
<input
309+
id="edit-quantity"
310+
type="number"
311+
min="1"
312+
step="1"
313+
bind:value={editQuantity}
314+
/>
315+
</div>
316+
303317
<div class="form-group">
304318
<label for="edit-notes">{t.itemDetail.notes}</label>
305319
<textarea

src/lib/db/queries.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ export async function updateItem(
602602
category_id: number;
603603
subcategory_id: number | null;
604604
purchase_price: number | null;
605+
quantity: number;
605606
notes: string | null;
606607
}>
607608
): Promise<void> {

src/lib/i18n/de.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const de = {
1313
notes: 'Notizen',
1414
items: 'Artikel',
1515
total: 'gesamt',
16+
showMore: 'Mehr anzeigen',
17+
remaining: 'übrig',
1618
done: 'erledigt',
1719
viewAll: 'Alle anzeigen',
1820
seeAll: 'Alle ansehen',

src/lib/i18n/en.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const en = {
1313
notes: 'Notes',
1414
items: 'items',
1515
total: 'total',
16+
showMore: 'Show more',
17+
remaining: 'remaining',
1618
done: 'done',
1719
viewAll: 'View All',
1820
seeAll: 'See All',

src/routes/inventory/+page.svelte

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
let refresh = getRefreshSignal();
2525
let selectedStatus = $state('all');
2626
let searchQuery = $state('');
27+
let pageSize = 20;
28+
let visibleCount = $state(20);
2729
/** @type {import('$lib/db/queries').Item | null} */
2830
let selectedItem = $state(null);
2931
@@ -102,6 +104,22 @@
102104
return result;
103105
});
104106
107+
let paginatedItems = $derived(filteredItems.slice(0, visibleCount));
108+
let hasMore = $derived(filteredItems.length > visibleCount);
109+
110+
function showMore() {
111+
visibleCount += pageSize;
112+
}
113+
114+
// Reset pagination when filters change
115+
$effect(() => {
116+
searchQuery;
117+
selectedCategoryId;
118+
selectedSubcategoryId;
119+
selectedStatus;
120+
visibleCount = pageSize;
121+
});
122+
105123
let statusCounts = $derived.by(() => {
106124
const catItems = selectedCategoryId === 0 ? items : items.filter(i => i.category_id === selectedCategoryId);
107125
const counts = { all: catItems.length, active: 0, used_up: 0, decluttered: 0 };
@@ -236,7 +254,7 @@
236254
</div>
237255
{:else}
238256
<div class="items-list">
239-
{#each filteredItems as item (item.id)}
257+
{#each paginatedItems as item (item.id)}
240258
{#if selectMode}
241259
<!-- svelte-ignore a11y_click_events_have_key_events -->
242260
<!-- svelte-ignore a11y_no_static_element_interactions -->
@@ -247,7 +265,7 @@
247265
<i class={item.category_icon ?? 'ri-box-3-line'}></i>
248266
</div>
249267
<div class="list-item-info">
250-
<h3 class="list-item-name">{item.name}</h3>
268+
<h3 class="list-item-name">{item.name}{#if item.quantity > 1} <span class="qty-badge">x{item.quantity}</span>{/if}</h3>
251269
<span class="list-item-sub">{item.subcategory_name || item.category_name}</span>
252270
</div>
253271
<div class="list-item-right">
@@ -275,7 +293,7 @@
275293
<i class={item.category_icon ?? 'ri-box-3-line'}></i>
276294
</div>
277295
<div class="list-item-info">
278-
<h3 class="list-item-name">{item.name}</h3>
296+
<h3 class="list-item-name">{item.name}{#if item.quantity > 1} <span class="qty-badge">x{item.quantity}</span>{/if}</h3>
279297
<span class="list-item-sub">{item.subcategory_name || item.category_name}</span>
280298
</div>
281299
<div class="list-item-right">
@@ -305,6 +323,11 @@
305323
</div>
306324
{/each}
307325
</div>
326+
{#if hasMore}
327+
<button class="show-more-btn" onclick={showMore}>
328+
{t.common.showMore} ({filteredItems.length - visibleCount} {t.common.remaining})
329+
</button>
330+
{/if}
308331
{/if}
309332
</main>
310333
@@ -500,6 +523,15 @@
500523
margin: 0;
501524
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
502525
}
526+
.qty-badge {
527+
font-size: 11px;
528+
font-weight: 700;
529+
color: white;
530+
background: var(--accent-pink);
531+
padding: 1px 6px;
532+
border-radius: 50px;
533+
vertical-align: middle;
534+
}
503535
.list-item-sub {
504536
font-size: 11px; color: var(--text-soft);
505537
text-transform: uppercase; letter-spacing: 0.3px;
@@ -552,4 +584,23 @@
552584
color: var(--accent-pink);
553585
transform: scale(0.85);
554586
}
587+
.show-more-btn {
588+
width: 100%;
589+
padding: 14px;
590+
margin-top: 12px;
591+
border: 1px dashed rgba(0, 0, 0, 0.12);
592+
border-radius: var(--radius-s);
593+
background: transparent;
594+
font-family: 'Poppins', sans-serif;
595+
font-size: 13px;
596+
font-weight: 600;
597+
color: var(--accent-pink);
598+
cursor: pointer;
599+
transition: 0.2s;
600+
-webkit-tap-highlight-color: transparent;
601+
}
602+
.show-more-btn:active {
603+
transform: scale(0.97);
604+
background: rgba(255, 107, 129, 0.04);
605+
}
555606
</style>

0 commit comments

Comments
 (0)