Login and Home

This commit is contained in:
Daniel Arantes Loverde
2026-02-04 16:55:29 -03:00
parent 78daaf1927
commit 33fc111459
90 changed files with 1707 additions and 303 deletions

View File

@@ -0,0 +1,88 @@
import Foundation
struct ApiEnvelope<T: Decodable>: Decodable {
let error: Bool
let code: String?
let message: String?
let result: T?
}
final class ApiService {
private let client: ApiClient
private var tokenStore: TokenStore
init(client: ApiClient = ApiClient(), tokenStore: TokenStore = DefaultTokenStore()) {
self.client = client
self.tokenStore = tokenStore
}
// MARK: - Auth
func requestOtp(email: String) async throws -> ApiEnvelope<EmptyResult> {
let body = try JSONEncoder().encode(["email": email])
let req = ApiRequest(path: "/api/customer/login", method: "POST", module: .customer, requiresAuth: false, body: body)
return try await client.send(req)
}
func validateOtp(email: String, otp: String) async throws -> ApiEnvelope<LoginResult> {
let body = try JSONEncoder().encode(["email": email, "otp": otp])
let req = ApiRequest(path: "/api/customer/login", method: "POST", module: .customer, requiresAuth: false, body: body)
let response: ApiEnvelope<LoginResult> = try await client.send(req)
if let token = response.result?.token {
tokenStore.jwt = token
}
return response
}
func profile() async throws -> ApiEnvelope<CustomerProfile> {
let req = ApiRequest(path: "/api/customer/profile", method: "GET", module: .customer, requiresAuth: true)
return try await client.send(req)
}
// MARK: - Stores
func listStores(lat: Double, lng: Double, category: String? = nil, search: String? = nil) async throws -> ApiEnvelope<[StoreSummary]> {
var items = [
URLQueryItem(name: "lat", value: String(lat)),
URLQueryItem(name: "lng", value: String(lng))
]
if let category {
items.append(URLQueryItem(name: "category", value: category))
}
if let search {
items.append(URLQueryItem(name: "search", value: search))
}
let req = ApiRequest(path: "/api/app/stores", method: "GET", module: .app, requiresAuth: true, queryItems: items)
return try await client.send(req)
}
}
// MARK: - DTOs
struct EmptyResult: Decodable {}
struct LoginResult: Decodable {
let token: String
let customer: CustomerProfile?
}
struct CustomerProfile: Decodable {
let id: String
let name: String
let email: String
let phoneNumber: String?
}
struct StoreSummary: Decodable {
let id: String
let name: String
let logo: String?
let cover: String?
let category: String?
let rating: Double?
let deliveryTime: String?
let deliveryFee: Double?
let distance: Double?
let isOpen: Bool?
let statusLabel: String?
}