diff --git a/src/views/PortfolioView.vue b/src/views/PortfolioView.vue index 5e0ea4a..340d522 100644 --- a/src/views/PortfolioView.vue +++ b/src/views/PortfolioView.vue @@ -76,7 +76,15 @@
Items
{{ filteredItems.length }} of {{ portfolio.items.length }}
-
+
+
+ +
@@ -183,6 +194,13 @@
Type{{ selectedItem.type }}
Grade{{ selectedItem.gradingCompany }} {{ selectedItem.grade }}
Variant{{ selectedItem.priceVariant }}
+
+ Rating +
+ + +
+
Quantity{{ selectedItem.quantity || 1 }}
Paid (each)${{ (selectedItem.purchasePrice || 0).toFixed(2) }}
Current Value${{ getCurrentValue(selectedItem).toFixed(2) }}
@@ -341,6 +359,7 @@ const stats = computed(() => store.getPortfolioStats(route.params.id) || { total const activeFilter = ref('all') const itemSearch = ref('') +const sortBy = ref('added') const editingName = ref(false) const editName = ref('') const nameInputRef = ref(null) @@ -409,8 +428,12 @@ const filters = [ const filteredItems = computed(() => { if (!portfolio.value) return [] - let items = portfolio.value.items + let items = [...portfolio.value.items] + + // Filter by type if (activeFilter.value !== 'all') items = items.filter(i => i.type === activeFilter.value) + + // Search if (itemSearch.value) { const q = itemSearch.value.toLowerCase() items = items.filter(i => @@ -418,6 +441,19 @@ const filteredItems = computed(() => { getItemSub(i).toLowerCase().includes(q) ) } + + // Sort + if (sortBy.value === 'value') { + items.sort((a, b) => (getCurrentValue(b) * (b.quantity || 1)) - (getCurrentValue(a) * (a.quantity || 1))) + } else if (sortBy.value === 'gain') { + items.sort((a, b) => getGain(b) - getGain(a)) + } else if (sortBy.value === 'name') { + items.sort((a, b) => getItemName(a).localeCompare(getItemName(b))) + } else { + // default: added (desc) + items.sort((a, b) => new Date(b.addedAt || 0) - new Date(a.addedAt || 0)) + } + return items }) @@ -505,6 +541,10 @@ function saveCurrentValue() { } } +function setRating(item, r) { + store.updateItem(portfolio.value.id, item.id, { rating: r }) +} + function onBulkImported(count) { refreshStatus.value = `Imported ${count} card${count !== 1 ? 's' : ''}` setTimeout(() => { refreshStatus.value = '' }, 3000) @@ -655,6 +695,7 @@ function deletePortfolio() { .stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 24px; } +.sort-mini-wrap { flex-shrink: 0; } .filter-tabs { display: flex; gap: 4px; } .filter-tab { background: none; @@ -683,6 +724,7 @@ function deletePortfolio() { .item-sealed-icon { width: 36px; height: 50px; display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; } .item-name { font-size: 13px; font-weight: 600; } .item-sub { font-size: 11px; color: var(--text-muted); margin-top: 1px; } +.item-rating { font-size: 11px; font-weight: 700; } .gain-cell { display: flex; flex-direction: column; font-size: 13px; font-variant-numeric: tabular-nums; } .gain-pct { font-size: 11px; } @@ -696,8 +738,15 @@ function deletePortfolio() { .panel-img { width: 120px; border-radius: 8px; pointer-events: none; -webkit-user-drag: none; user-drag: none; } .panel-right { flex: 1; } .panel-info-grid { display: flex; flex-direction: column; gap: 6px; } -.info-row { display: flex; justify-content: space-between; font-size: 13px; padding: 4px 0; border-bottom: 1px solid var(--border-subtle); } +.info-row { display: flex; justify-content: space-between; align-items: center; font-size: 13px; padding: 4px 0; border-bottom: 1px solid var(--border-subtle); } .info-label { color: var(--text-muted); } + +.rating-picker { display: flex; align-items: center; gap: 2px; } +.rating-picker button { background: none; border: none; color: var(--text-muted); font-size: 18px; cursor: pointer; padding: 0 2px; line-height: 1; transition: color 0.1s; } +.rating-picker button.active { color: var(--accent); } +.rating-clear { font-size: 11px !important; margin-left: 6px; opacity: 0.6; } +.rating-clear:hover { opacity: 1; } + .panel-chart-section { border-top: 1px solid var(--border); padding-top: 20px; } /* eBay price fetch */