Ship full-featured mobile clients with auth, payments, QRs, push notifications, and iOS polish including Figtree typography, app icons, and QR previews. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
import Foundation
|
||||
|
||||
struct Envelope<T: Decodable>: Decodable { let data: T }
|
||||
|
||||
struct PagedEnvelope<T: Decodable>: Decodable {
|
||||
let data: [T]
|
||||
let meta: PageMeta?
|
||||
}
|
||||
|
||||
struct PageMeta: Decodable {
|
||||
let currentPage: Int?
|
||||
let lastPage: Int?
|
||||
let perPage: Int?
|
||||
let total: Int?
|
||||
}
|
||||
|
||||
struct LoginRequest: Encodable {
|
||||
let email: String
|
||||
let password: String
|
||||
let deviceName = "Ladill Mini iOS"
|
||||
}
|
||||
|
||||
struct LoginResult: Decodable {
|
||||
let token: String
|
||||
let user: User
|
||||
}
|
||||
|
||||
struct RegisterRequest: Encodable {
|
||||
let name: String
|
||||
let email: String
|
||||
let password: String
|
||||
let passwordConfirmation: String
|
||||
let company: String?
|
||||
let address: String
|
||||
let city: String
|
||||
let state: String
|
||||
let country: String
|
||||
let zipcode: String
|
||||
let phoneCc: String
|
||||
let phone: String
|
||||
let mobileCc: String?
|
||||
let mobile: String?
|
||||
let terms: Bool
|
||||
let deviceName = "Ladill Mini iOS"
|
||||
}
|
||||
|
||||
struct User: Decodable {
|
||||
let id: Int64
|
||||
let publicId: String?
|
||||
let name: String?
|
||||
let email: String?
|
||||
let avatarUrl: String?
|
||||
let actingAccount: Account?
|
||||
}
|
||||
|
||||
struct Account: Decodable {
|
||||
let id: Int64
|
||||
let publicId: String?
|
||||
let name: String?
|
||||
let email: String?
|
||||
}
|
||||
|
||||
struct Overview: Decodable {
|
||||
let currency: String?
|
||||
let todayTakingsMinor: Int64?
|
||||
let todayCount: Int?
|
||||
let paymentQrCount: Int?
|
||||
let walletBalanceMinor: Int64?
|
||||
let recentPayments: [Payment]?
|
||||
}
|
||||
|
||||
struct Payment: Decodable, Identifiable {
|
||||
let id: Int64
|
||||
let reference: String?
|
||||
let amountMinor: Int64?
|
||||
let merchantAmountMinor: Int64?
|
||||
let platformFeeMinor: Int64?
|
||||
let currency: String?
|
||||
let status: String?
|
||||
let payerName: String?
|
||||
let payerEmail: String?
|
||||
let payerPhone: String?
|
||||
let payerNote: String?
|
||||
let qrCodeId: Int64?
|
||||
let qrLabel: String?
|
||||
let paidAt: String?
|
||||
let createdAt: String?
|
||||
}
|
||||
|
||||
struct PaymentQr: Decodable, Identifiable {
|
||||
let id: Int64
|
||||
let label: String
|
||||
let businessName: String?
|
||||
let branchLabel: String?
|
||||
let currency: String?
|
||||
let shortCode: String?
|
||||
let publicUrl: String?
|
||||
let isActive: Bool?
|
||||
let scansTotal: Int?
|
||||
let previewUrl: String?
|
||||
let createdAt: String?
|
||||
let updatedAt: String?
|
||||
}
|
||||
|
||||
struct CreatePaymentQrRequest: Encodable {
|
||||
let label: String
|
||||
let businessName: String
|
||||
let branchLabel: String?
|
||||
}
|
||||
|
||||
struct UpdatePaymentQrRequest: Encodable {
|
||||
var label: String?
|
||||
var businessName: String?
|
||||
var branchLabel: String?
|
||||
var isActive: Bool?
|
||||
}
|
||||
|
||||
struct Payouts: Decodable {
|
||||
let currency: String?
|
||||
let totalRevenueMinor: Int64?
|
||||
let walletBalanceMinor: Int64?
|
||||
let accountWalletUrl: String?
|
||||
}
|
||||
|
||||
struct AccountSettings: Decodable {
|
||||
let profile: ProfileInfo
|
||||
let notifications: NotificationPrefs
|
||||
}
|
||||
|
||||
struct ProfileInfo: Decodable {
|
||||
let name: String?
|
||||
let email: String?
|
||||
let phone: String?
|
||||
let phoneCc: String?
|
||||
}
|
||||
|
||||
struct NotificationPrefs: Codable {
|
||||
var notifyEmail: String?
|
||||
var productUpdates: Bool?
|
||||
var notifyRegistrations: Bool?
|
||||
var notifyPayouts: Bool?
|
||||
}
|
||||
|
||||
struct UpdateSettingsRequest: Encodable {
|
||||
let notifyEmail: String?
|
||||
let productUpdates: Bool
|
||||
let notifyRegistrations: Bool
|
||||
let notifyPayouts: Bool
|
||||
}
|
||||
|
||||
struct UpdateProfileRequest: Encodable {
|
||||
let name: String
|
||||
let phoneCc: String?
|
||||
let phone: String?
|
||||
}
|
||||
|
||||
struct AvatarResult: Decodable { let avatarUrl: String? }
|
||||
|
||||
struct ChangePasswordRequest: Encodable {
|
||||
let currentPassword: String
|
||||
let password: String
|
||||
let passwordConfirmation: String
|
||||
}
|
||||
|
||||
struct MessageResponse: Decodable { let message: String? }
|
||||
|
||||
struct AfiaChatRequest: Encodable {
|
||||
let message: String
|
||||
let history: [AfiaChatTurn]
|
||||
}
|
||||
|
||||
struct AfiaChatTurn: Encodable {
|
||||
let role: String
|
||||
let text: String
|
||||
}
|
||||
|
||||
struct AfiaChatResponse: Decodable {
|
||||
let reply: String?
|
||||
let message: String?
|
||||
}
|
||||
|
||||
struct WalletInfo: Decodable {
|
||||
let currency: String?
|
||||
let balanceMinor: Int64?
|
||||
let spentMinor: Int64?
|
||||
let creditedMinor: Int64?
|
||||
}
|
||||
|
||||
struct TopupRequest: Encodable { let amount: Double }
|
||||
|
||||
struct CheckoutUrl: Decodable { let checkoutUrl: String }
|
||||
|
||||
struct PayoutAccountWrapper: Decodable { let payoutAccount: PayoutAccount? }
|
||||
|
||||
struct PayoutAccount: Decodable {
|
||||
let accountType: String?
|
||||
let accountName: String?
|
||||
let accountNumber: String?
|
||||
let bankCode: String?
|
||||
let bankName: String?
|
||||
let currency: String?
|
||||
}
|
||||
|
||||
struct UpdatePayoutAccountRequest: Encodable {
|
||||
let accountType: String
|
||||
let accountName: String
|
||||
let accountNumber: String
|
||||
let bankCode: String
|
||||
let bankName: String
|
||||
let currency: String
|
||||
}
|
||||
|
||||
struct Bank: Decodable, Identifiable {
|
||||
var id: String { code }
|
||||
let name: String
|
||||
let code: String
|
||||
}
|
||||
|
||||
struct WithdrawRequest: Encodable { let amount: Double }
|
||||
|
||||
struct Withdrawal: Decodable, Identifiable {
|
||||
let id: Int64
|
||||
let amountGhs: Double?
|
||||
let status: String?
|
||||
let createdAt: String?
|
||||
}
|
||||
|
||||
struct SupportTicket: Decodable, Identifiable {
|
||||
let id: Int64
|
||||
let ticketRef: String?
|
||||
let subject: String?
|
||||
let status: String?
|
||||
let priority: String?
|
||||
let hasReply: Bool?
|
||||
let createdAt: String?
|
||||
let message: String?
|
||||
let reply: String?
|
||||
let repliedAt: String?
|
||||
}
|
||||
|
||||
struct CreateTicketRequest: Encodable {
|
||||
let subject: String
|
||||
let message: String
|
||||
let priority: String
|
||||
}
|
||||
|
||||
struct NotificationsListResponse: Decodable {
|
||||
let data: [AppNotification]
|
||||
let unreadCount: Int?
|
||||
}
|
||||
|
||||
struct AppNotification: Decodable, Identifiable {
|
||||
let id: String
|
||||
let type: String?
|
||||
let title: String
|
||||
let message: String
|
||||
let icon: String?
|
||||
let milestone: String?
|
||||
let url: String?
|
||||
let readAt: String?
|
||||
let createdAt: String?
|
||||
|
||||
var isRead: Bool { readAt != nil }
|
||||
}
|
||||
|
||||
struct UnreadCountEnvelope: Decodable { let unreadCount: Int? }
|
||||
|
||||
struct PushTokenRequest: Encodable {
|
||||
let token: String
|
||||
let platform = "ios"
|
||||
let deviceName = "Ladill Mini iOS"
|
||||
}
|
||||
|
||||
struct Country: Identifiable, Hashable {
|
||||
var id: String { code }
|
||||
let code: String
|
||||
let name: String
|
||||
let dialCode: String
|
||||
let states: [String]
|
||||
}
|
||||
|
||||
enum Countries {
|
||||
static let all: [Country] = [
|
||||
Country(code: "GH", name: "Ghana", dialCode: "233", states: [
|
||||
"Ahafo", "Ashanti", "Bono", "Bono East", "Central", "Eastern", "Greater Accra",
|
||||
"North East", "Northern", "Oti", "Savannah", "Upper East", "Upper West", "Volta",
|
||||
"Western", "Western North",
|
||||
]),
|
||||
Country(code: "NG", name: "Nigeria", dialCode: "234", states: [
|
||||
"Abia", "Abuja FCT", "Adamawa", "Akwa Ibom", "Anambra", "Bauchi", "Bayelsa", "Benue",
|
||||
"Borno", "Cross River", "Delta", "Ebonyi", "Edo", "Ekiti", "Enugu", "Gombe", "Imo",
|
||||
"Jigawa", "Kaduna", "Kano", "Katsina", "Kebbi", "Kogi", "Kwara", "Lagos", "Nasarawa",
|
||||
"Niger", "Ogun", "Ondo", "Osun", "Oyo", "Plateau", "Rivers", "Sokoto", "Taraba",
|
||||
"Yobe", "Zamfara",
|
||||
]),
|
||||
Country(code: "KE", name: "Kenya", dialCode: "254", states: [
|
||||
"Baringo", "Bomet", "Bungoma", "Busia", "Elgeyo-Marakwet", "Embu", "Garissa",
|
||||
"Homa Bay", "Isiolo", "Kajiado", "Kakamega", "Kericho", "Kiambu", "Kilifi",
|
||||
"Kirinyaga", "Kisii", "Kisumu", "Kitui", "Kwale", "Laikipia", "Lamu", "Machakos",
|
||||
"Makueni", "Mandera", "Marsabit", "Meru", "Migori", "Mombasa", "Murang'a", "Nairobi",
|
||||
"Nakuru", "Nandi", "Narok", "Nyamira", "Nyandarua", "Nyeri", "Samburu", "Siaya",
|
||||
"Taita-Taveta", "Tana River", "Tharaka-Nithi", "Trans Nzoia", "Turkana",
|
||||
"Uasin Gishu", "Vihiga", "Wajir", "West Pokot",
|
||||
]),
|
||||
Country(code: "ZA", name: "South Africa", dialCode: "27", states: [
|
||||
"Eastern Cape", "Free State", "Gauteng", "KwaZulu-Natal", "Limpopo", "Mpumalanga",
|
||||
"North West", "Northern Cape", "Western Cape",
|
||||
]),
|
||||
Country(code: "GB", name: "United Kingdom", dialCode: "44", states: [
|
||||
"England", "Northern Ireland", "Scotland", "Wales",
|
||||
]),
|
||||
Country(code: "US", name: "United States", dialCode: "1", states: [
|
||||
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut",
|
||||
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa",
|
||||
"Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan",
|
||||
"Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
|
||||
"New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
|
||||
"North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
|
||||
"South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
|
||||
"Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming",
|
||||
]),
|
||||
]
|
||||
|
||||
static var `default`: Country { all[0] }
|
||||
}
|
||||
|
||||
enum LoadState<T> {
|
||||
case idle
|
||||
case loading
|
||||
case success(T)
|
||||
case failure(String)
|
||||
}
|
||||
Reference in New Issue
Block a user