- SwiftUI + async/await architecture - Barcode scanning with AVFoundation - Product display with score ring, NOVA badge, nutrition - Alternatives with sort/filter - Auth (login/register) - Favorites & history - Account management - Dark theme - Connected to food.payfrit.com API (Open Food Facts proxy) Co-Authored-By: Claude <noreply@anthropic.com>
38 lines
1.2 KiB
Swift
38 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
struct ScanHistoryItem: Identifiable {
|
|
let id: Int
|
|
let product: Product
|
|
let scannedAt: Date
|
|
|
|
init(json: [String: Any]) {
|
|
id = JSON.parseInt(json["id"] ?? json["historyId"])
|
|
|
|
if let productData = json["product"] as? [String: Any] {
|
|
product = Product(json: productData)
|
|
} else {
|
|
product = Product(json: json)
|
|
}
|
|
|
|
if let dateString = json["scannedAt"] as? String ?? json["ScannedAt"] as? String {
|
|
let formatter = ISO8601DateFormatter()
|
|
scannedAt = formatter.date(from: dateString) ?? Date()
|
|
} else if let timestamp = json["scannedAt"] as? Double ?? json["ScannedAt"] as? Double {
|
|
scannedAt = Date(timeIntervalSince1970: timestamp)
|
|
} else {
|
|
scannedAt = Date()
|
|
}
|
|
}
|
|
|
|
init(id: Int, product: Product, scannedAt: Date = Date()) {
|
|
self.id = id
|
|
self.product = product
|
|
self.scannedAt = scannedAt
|
|
}
|
|
|
|
var formattedDate: String {
|
|
let formatter = RelativeDateTimeFormatter()
|
|
formatter.unitsStyle = .abbreviated
|
|
return formatter.localizedString(for: scannedAt, relativeTo: Date())
|
|
}
|
|
}
|