Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
1 change: 1 addition & 0 deletions TorqueNet/Core/Model/UploadError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ enum UploadError: LocalizedError {
return "Network error. Please check your connection."
}
}

}
1 change: 1 addition & 0 deletions TorqueNet/Core/Navigation/Route.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ enum Route: Hashable {
case changePassword
case notification
case editProfile
case manageAuction
}
4 changes: 4 additions & 0 deletions TorqueNet/Core/Navigation/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,9 @@ func viewForRoute(_ route: Route, router: Router) -> some View{
EditProfileView()
.navigationBarBackButtonHidden()

case .manageAuction:
ManageAuctionsView()
.navigationBarBackButtonHidden()

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Combine
struct AuctionUploadModel: Identifiable, Codable {
let id: String
let imageUrls: [String]
let sellerId: String
let carTitle: String
let subtitle: String
let lotNumber: String
Expand Down Expand Up @@ -61,6 +62,7 @@ struct AuctionUploadModel: Identifiable, Codable {
enum CodingKeys: String, CodingKey {
case id
case imageUrls = "image_urls"
case sellerId = "seller_id"
case carTitle = "car_title"
case subtitle
case lotNumber = "lot_number"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class UploadAuctionUseCase {

func executeCreateAuction(
images: [UIImage],
sellerId: String,
carTitle: String,
subtitle: String,
lotNumber: String,
Expand Down Expand Up @@ -104,6 +105,7 @@ class UploadAuctionUseCase {
let auction = AuctionUploadModel(
id: auctionId,
imageUrls: imageUrls,
sellerId: sellerId,
carTitle: carTitle,
subtitle: subtitle,
lotNumber: lotNumber,
Expand Down Expand Up @@ -158,6 +160,7 @@ class UploadAuctionUseCase {
let updatedAuction = AuctionUploadModel(
id: auctionId,
imageUrls: auction.imageUrls,
sellerId: auction.sellerId,
carTitle: auction.carTitle,
subtitle: auction.subtitle,
lotNumber: auction.lotNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import UIKit
import SwiftUI
import FirebaseAuth

@MainActor
class AuctionUploadViewModel: ObservableObject {
Expand Down Expand Up @@ -199,6 +200,7 @@ class AuctionUploadViewModel: ObservableObject {

let result = await uploadUseCase.executeCreateAuction(
images: form.selectedImages,
sellerId: Auth.auth().currentUser?.uid ?? "",
carTitle: form.carTitle,
subtitle: form.subtitle,
lotNumber: form.lotNumber,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// ManageAuctionRepositoryImpl.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

import Foundation
import FirebaseCore

class ManageAuctionRepositoryImpl: ManageAuctionRepository {
static let shared = ManageAuctionRepositoryImpl()

func fetchSellerAuctions(sellerId: String) async -> Result<[ManageAuctionItem], UploadError> {
do {
let snapshot = try await FirestoreConstants.AuctionsCollection
.whereField("seller_id", isEqualTo: sellerId)
.getDocuments()

let auctions: [ManageAuctionItem] = snapshot.documents.compactMap { document in
guard let model = try? document.data(as: AuctionUploadModel.self) else {
return nil
}
return ManageAuctionItem(from: model)
}

return .success(auctions)

} catch {
return .failure(
.firestoreFetchFailed(error.localizedDescription, "seller auctions")
)
}
}

func updateAuctionDetails(auctionId: String, status: AuctionStatus, startDate: Date, endDate: Date) async -> Result<Void, UploadError> {
do {
let updateData: [String: Any] = [
"auction_status": status.rawValue,
"created_at": Timestamp(date: startDate),
"auction_end_date": Timestamp(date: endDate),
"updated_at": Timestamp(date: Date())
]

try await FirestoreConstants.AuctionsCollection
.document(auctionId)
.updateData(updateData)

return .success(())

} catch {
return .failure(.firestoreUpdateFailed(error.localizedDescription))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// ManageAuctionItem.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

import Foundation

struct ManageAuctionItem: Identifiable {
let id: String
let carTitle: String
let imageUrl: String
let lotNumber: String
let status: AuctionStatus
let startDate: Date
let endDate: Date
let startingBid: Double
let currentBid: Double
let bidCount: Int
let sellerId: String

init(from model: AuctionUploadModel) {
self.id = model.id
self.carTitle = model.carTitle
self.imageUrl = model.imageUrls.first ?? ""
self.lotNumber = model.lotNumber
self.status = AuctionStatus(rawValue: model.auctionStatus) ?? .ongoing
self.startDate = model.createdAt.dateValue()
self.endDate = model.auctionEndDate.dateValue()
self.startingBid = model.startingBid
self.currentBid = model.currentBid
self.bidCount = model.bidCount
self.sellerId = model.seller
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ManageAuctionRepository.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

import Foundation

protocol ManageAuctionRepository {
func fetchSellerAuctions(sellerId: String) async -> Result<[ManageAuctionItem], UploadError>
func updateAuctionDetails(auctionId: String, status: AuctionStatus, startDate: Date, endDate: Date) async -> Result<Void, UploadError>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// FetchSellerAuctionUseCase.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

class FetchSellerAuctionsUseCase {
private let repository: ManageAuctionRepository

init(repository: ManageAuctionRepository) {
self.repository = repository
}

func execute(sellerId: String) async -> Result<[ManageAuctionItem], UploadError> {
return await repository.fetchSellerAuctions(sellerId: sellerId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// UpdateAuctionUseCase.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

import Foundation

class UpdateAuctionUseCase {
private let repository: ManageAuctionRepository

init(repository: ManageAuctionRepository) {
self.repository = repository
}

func execute(auctionId: String, status: AuctionStatus, startDate: Date, endDate: Date) async -> Result<Void, UploadError> {
if endDate <= startDate {
return .failure(.invalidData("End date must be after start date"))
}

if status == .upcoming && startDate <= Date() {
return .failure(.invalidData("Scheduled auctions must have a future start date"))
}

return await repository.updateAuctionDetails(
auctionId: auctionId,
status: status,
startDate: startDate,
endDate: endDate
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ManageAuctionUiState.swift
// TorqueNet
//
// Created by MAC on 20/02/2026.
//

struct ManageAuctionUiState {
var auctions: [ManageAuctionItem] = []
var filteredAuctions: [ManageAuctionItem] = []
var selectedFilter: AuctionStatus? = nil

// var isLoading: Bool = false
var errorMessage: String = ""
// var hasError: Bool = false
var showError: Bool = false
var auctionState: FetchState = .good
var showEditSheet: Bool = false
var selectedAuction: ManageAuctionItem? = nil
}
Loading