MAJOR UPPDATE: "First Ai"
feat: add AI categorization for products and enhance user management - Integrated AI service for category suggestions in receipt import and product management. - Added premium subscription feature for users with corresponding API endpoints. - Implemented admin interface for managing pending product suggestions. - Enhanced user management to include premium status and corresponding UI updates. - Updated database schema to support new fields for premium status and product status.
This commit is contained in:
@@ -2,6 +2,14 @@
|
||||
|
||||
import { useRef, useState, useEffect } from 'react';
|
||||
|
||||
type CategorySuggestion = {
|
||||
categoryId: number;
|
||||
categoryName: string;
|
||||
path: string;
|
||||
confidence: 'high' | 'medium' | 'low';
|
||||
usedFallback: boolean;
|
||||
};
|
||||
|
||||
type ParsedItem = {
|
||||
rawName: string;
|
||||
quantity: number;
|
||||
@@ -11,6 +19,7 @@ type ParsedItem = {
|
||||
matchedProductName?: string;
|
||||
suggestedProductId?: number;
|
||||
suggestedProductName?: string;
|
||||
categorySuggestion?: CategorySuggestion;
|
||||
};
|
||||
|
||||
type Product = { id: number; name: string; canonicalName: string | null };
|
||||
@@ -27,6 +36,7 @@ type RowState = {
|
||||
editQty: string;
|
||||
editUnit: string;
|
||||
matchSource: 'alias' | 'suggestion' | 'manual' | 'none';
|
||||
categorySuggestion?: CategorySuggestion;
|
||||
};
|
||||
|
||||
const UNITS = ['st', 'kg', 'g', 'l', 'dl', 'cl', 'ml', 'förp', 'pak', 'burk', 'flaska'];
|
||||
@@ -116,6 +126,7 @@ export default function ReceiptImportClient() {
|
||||
editQty: String(item.quantity),
|
||||
editUnit: item.unit,
|
||||
matchSource: 'none',
|
||||
categorySuggestion: item.categorySuggestion,
|
||||
};
|
||||
}),
|
||||
);
|
||||
@@ -272,6 +283,13 @@ export default function ReceiptImportClient() {
|
||||
{UNITS.map((u) => <option key={u} value={u}>{u}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
{row.categorySuggestion && row.matchSource === 'none' && (
|
||||
<div style={{ marginTop: '0.5rem', fontSize: '0.8rem', color: '#7c3aed', background: '#f5f3ff', border: '1px solid #ddd6fe', borderRadius: '5px', padding: '4px 8px', display: 'inline-flex', alignItems: 'center', gap: '0.4rem' }}>
|
||||
<span>✨</span>
|
||||
<span>AI-förslag: <strong>{row.categorySuggestion.path}</strong></span>
|
||||
{row.categorySuggestion.usedFallback && <span style={{ color: '#b45309' }}>(osäker)</span>}
|
||||
</div>
|
||||
)}
|
||||
{row.selectedProductId !== '' && row.matchSource !== 'alias' && (
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', marginTop: '0.5rem', fontSize: '0.82rem', color: '#555', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={row.saveAlias} onChange={(e) => updateRow(i, { saveAlias: e.target.checked })} />
|
||||
|
||||
Reference in New Issue
Block a user