Initial commit

This commit is contained in:
Wira Basalamah
2026-04-24 04:55:24 +07:00
commit 8f0b001501
128 changed files with 9366 additions and 0 deletions

View File

@ -0,0 +1,19 @@
//
// GradientView.swift
// Emoney Info
//
// Created by Wira Irawan on 29/07/24.
//
import Foundation
import UIKit
class GradientView: UIView {
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
var gradientLayer: CAGradientLayer {
return self.layer as! CAGradientLayer
}
}

View File

@ -0,0 +1,177 @@
import Foundation
/// Type-safe localization helper.
/// Usage: L10n.checkBalance returns localized String automatically
/// Works in both UIKit (as String) and SwiftUI (via Text(L10n.xxx))
enum L10n {
// MARK: - Home
static var availableBalance: String { s("availableBalance") }
static var cardTapInstruction: String { s("cardTapInstruction") }
static var cardTypeDefault: String { s("cardTypeDefault") }
static var tapCardHere: String { s("tapCardHere") }
static var tapCardHint: String { s("tapCardHint") }
static var checkBalance: String { s("checkBalance") }
static var lastTransaction: String { s("lastTransaction") }
static var viewFullHistory: String { s("viewFullHistory") }
static var copiedToClipboard: String { s("copiedToClipboard") }
static var transactionDefault: String { s("transactionDefault") }
static var transactionStatusSuccess: String { s("transactionStatusSuccess") }
static var noCard: String { s("noCard") }
// MARK: - Card / NFC
static var cardType: String { s("cardType") }
static var cardNumber: String { s("cardNumber") }
static var balance: String { s("balance") }
static var scanMessage: String { s("scanMessage") }
static var readFinish: String { s("readFinish") }
static var readFailed: String { s("readFailed") }
static var updateBalance: String { s("updateBalance") }
static var payment: String { s("payment") }
static var topup: String { s("topup") }
static var unknown: String { s("unknown") }
static var void: String { s("void") }
static var reactivation: String { s("reactivation") }
static var statementFee: String { s("statementFee") }
static var gracePeriod: String { s("gracePeriod") }
static var refund: String { s("refund") }
static var close: String { s("close") }
static var atu: String { s("atu") }
// MARK: - History
static var historyTitle: String { s("historyTitle") }
static var recentActivity: String { s("recentActivity") }
static var filterAllTime: String { s("filterAllTime") }
static var filterToday: String { s("filterToday") }
static var filterThisMonth: String { s("filterThisMonth") }
static var filterThisWeek: String { s("filterThisWeek") }
static var noTransactionsFound: String { s("noTransactionsFound") }
static var exportPDF: String { s("exportPDF") }
static var transactionHistory: String { s("transactionHistory") }
// MARK: - Settings
static var settingsTitle: String { s("settingsTitle") }
static var premiumBadge: String { s("premiumBadge") }
static var premiumTitle: String { s("premiumTitle") }
static var premiumDesc: String { s("premiumDesc") }
static var upgradeNow: String { s("upgradeNow") }
static var sectionGeneral: String { s("sectionGeneral") }
static var languageTitle: String { s("languageTitle") }
static var languageValue: String { s("languageValue") }
static var showCardNumberTitle: String { s("showCardNumberTitle") }
static var showCardNumberDesc: String { s("showCardNumberDesc") }
static var sectionApp: String { s("sectionApp") }
static var notificationsTitle: String { s("notificationsTitle") }
static var notificationsDesc: String { s("notificationsDesc") }
static var helpCenterTitle: String { s("helpCenterTitle") }
static var helpCenterDesc: String { s("helpCenterDesc") }
static var aboutAppTitle: String { s("aboutAppTitle") }
static var aboutAppDesc: String { s("aboutAppDesc") }
// MARK: - Terms & Conditions
static var termsLastUpdated: String { s("termsLastUpdated") }
static var termsTitleRegular: String { s("termsTitleRegular") }
static var termsTitleBold: String { s("termsTitleBold") }
static var termsSubtitle: String { s("termsSubtitle") }
static var termsSec1Title: String { s("termsSec1Title") }
static var termsSec1Body: String { s("termsSec1Body") }
static var termsSec2Title: String { s("termsSec2Title") }
static var termsSec2Body: String { s("termsSec2Body") }
static var termsSec2Bullet1: String { s("termsSec2Bullet1") }
static var termsSec2Bullet2: String { s("termsSec2Bullet2") }
static var termsSec2Bullet3: String { s("termsSec2Bullet3") }
static var termsSec3Title: String { s("termsSec3Title") }
static var termsSec3Body: String { s("termsSec3Body") }
static var termsSec3Bullet1: String { s("termsSec3Bullet1") }
static var termsSec3Bullet2: String { s("termsSec3Bullet2") }
static var termsContactTitle: String { s("termsContactTitle") }
static var termsContactDesc: String { s("termsContactDesc") }
static var termsContactButton: String { s("termsContactButton") }
// MARK: - Privacy Policy
static var privacyLastUpdated: String { s("privacyLastUpdated") }
static var privacySectionNfcTitle: String { s("privacySectionNfcTitle") }
static var privacySectionNfcBody: String { s("privacySectionNfcBody") }
static var privacySectionNoStorageTitle: String { s("privacySectionNoStorageTitle") }
static var privacySectionNoStorageBody: String { s("privacySectionNoStorageBody") }
static var privacySectionReadOnlyTitle: String { s("privacySectionReadOnlyTitle") }
static var privacySectionReadOnlyBody: String { s("privacySectionReadOnlyBody") }
static var privacyContactTitle: String { s("privacyContactTitle") }
static var privacyContactDesc: String { s("privacyContactDesc") }
static var privacyContactButton: String { s("privacyContactButton") }
// MARK: - About
static var aboutAppDescription: String { s("aboutAppDescription") }
static var aboutChipNfc: String { s("aboutChipNfc") }
static var aboutChipRealtime: String { s("aboutChipRealtime") }
static var aboutChipMulti: String { s("aboutChipMulti") }
static var aboutTerms: String { s("aboutTerms") }
static var aboutPrivacy: String { s("aboutPrivacy") }
static var aboutConnectTitle: String { s("aboutConnectTitle") }
static var aboutConnectDesc: String { s("aboutConnectDesc") }
static var maskTitle: String { s("maskTitle") }
static var maskDesc: String { s("maskDesc") }
static var supportCardTitle: String { s("supportCardTitle") }
static var supportCardDesc: String { s("supportCardDesc") }
static var aboutTitle: String { s("aboutTitle") }
static var version: String { s("versi") }
static var footerCopyright: String { s("footerCopyright") }
static var reportIssue: String { s("reportIssue") }
// MARK: - FAQ
static var faqHeaderTitle: String { s("faqHeaderTitle") }
static var faqSearchPlaceholder: String { s("faqSearchPlaceholder") }
static var faqFilterAll: String { s("faqFilterAll") }
static var faqNoResults: String { s("faqNoResults") }
static var faqHelpCardTitle: String { s("faqHelpCardTitle") }
static var faqHelpCardDesc: String { s("faqHelpCardDesc") }
static var faqEmailSupport: String { s("faqEmailSupport") }
// FAQ Categories
static var faqCategoryCard: String { s("faqCategoryCard") }
static var faqCategoryTransaction: String { s("faqCategoryTransaction") }
static var faqCategoryBalance: String { s("faqCategoryBalance") }
static var faqCategoryApp: String { s("faqCategoryApp") }
// FAQ Questions & Answers Card
static var faqQ_cardCompatible: String { s("faqQ_cardCompatible") }
static var faqA_cardCompatible: String { s("faqA_cardCompatible") }
static var faqQ_cardNotDetected: String { s("faqQ_cardNotDetected") }
static var faqA_cardNotDetected: String { s("faqA_cardNotDetected") }
static var faqQ_cardReadFailed: String { s("faqQ_cardReadFailed") }
static var faqA_cardReadFailed: String { s("faqA_cardReadFailed") }
// FAQ Questions & Answers Transaction
static var faqQ_txNotShown: String { s("faqQ_txNotShown") }
static var faqA_txNotShown: String { s("faqA_txNotShown") }
static var faqQ_txExportPDF: String { s("faqQ_txExportPDF") }
static var faqA_txExportPDF: String { s("faqA_txExportPDF") }
// FAQ Questions & Answers Balance
static var faqQ_balanceWrong: String { s("faqQ_balanceWrong") }
static var faqA_balanceWrong: String { s("faqA_balanceWrong") }
static var faqQ_balanceTopup: String { s("faqQ_balanceTopup") }
static var faqA_balanceTopup: String { s("faqA_balanceTopup") }
// FAQ Questions & Answers App
static var faqQ_appLanguage: String { s("faqQ_appLanguage") }
static var faqA_appLanguage: String { s("faqA_appLanguage") }
static var faqQ_appMaskNumber: String { s("faqQ_appMaskNumber") }
static var faqA_appMaskNumber: String { s("faqA_appMaskNumber") }
// MARK: - Tab Bar
static var tabEmoney: String { s("tabEmoney") }
static var tabSettings: String { s("tabSettings") }
// MARK: - Private
private static func s(_ key: String) -> String {
NSLocalizedString(key, comment: "")
}
}

View File

@ -0,0 +1,15 @@
//
// Station.swift
// Emoney Info
//
// Created by Wira Basalamah on 05/04/26.
//
struct Station {
let id: Int
let name: String
let subName: String
let latitude: String
let longitude: String
}

View File

@ -0,0 +1,59 @@
import UIKit
enum Theme {
// MARK: - Colors
enum Color {
static let primary = UIColor(hex: "#7AD4D1")
static let secondary = UIColor(hex: "#5D7D7B")
static let success = UIColor(hex: "#34C759")
static let background = UIColor(hex: "#F3F3F8")
static let card = UIColor.white
static let textPrimary = UIColor(hex: "#1A1A2E")
static let textSecondary = UIColor(hex: "#8E8E93")
}
// MARK: - Font Sizes
enum FontSize {
static let title: CGFloat = 24
static let subtitle: CGFloat = 18
static let body: CGFloat = 16
static let caption: CGFloat = 12
}
// MARK: - Fonts
enum Font {
static func title(weight: UIFont.Weight = .bold) -> UIFont {
.systemFont(ofSize: FontSize.title, weight: weight)
}
static func subtitle(weight: UIFont.Weight = .semibold) -> UIFont {
.systemFont(ofSize: FontSize.subtitle, weight: weight)
}
static func body(weight: UIFont.Weight = .regular) -> UIFont {
.systemFont(ofSize: FontSize.body, weight: weight)
}
static func caption(weight: UIFont.Weight = .regular) -> UIFont {
.systemFont(ofSize: FontSize.caption, weight: weight)
}
}
}
// MARK: - UIColor hex initializer
private extension UIColor {
convenience init(hex: String) {
var sanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
if sanitized.hasPrefix("#") { sanitized.removeFirst() }
var rgb: UInt64 = 0
Scanner(string: sanitized).scanHexInt64(&rgb)
let r = CGFloat((rgb >> 16) & 0xFF) / 255
let g = CGFloat((rgb >> 8) & 0xFF) / 255
let b = CGFloat( rgb & 0xFF) / 255
self.init(red: r, green: g, blue: b, alpha: 1)
}
}

View File

@ -0,0 +1,50 @@
//
// ToastHelper.swift
// NewTonNfcCardLib
//
// Created by Alina Alinovna on 23.10.2020.
// Copyright © 2020 Facebook. All rights reserved.
//
import Foundation
import UIKit
class ToastHelper {
static func showToast(message : String) {
let toastView = UILabel()
toastView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
toastView.textColor = UIColor.white
toastView.textAlignment = .center
toastView.font = UIFont.preferredFont(forTextStyle: .caption1)
toastView.layer.cornerRadius = 25
toastView.layer.masksToBounds = true
toastView.text = message
toastView.numberOfLines = 0
toastView.alpha = 0
toastView.translatesAutoresizingMaskIntoConstraints = false
let window = UIApplication.shared.delegate?.window!
window?.addSubview(toastView)
let horizontalCenterContraint: NSLayoutConstraint = NSLayoutConstraint(item: toastView, attribute: .centerX, relatedBy: .equal, toItem: window, attribute: .centerX, multiplier: 1, constant: 0)
let widthContraint: NSLayoutConstraint = NSLayoutConstraint(item: toastView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 275)
let verticalContraint: [NSLayoutConstraint] = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(>=200)-[loginView(==50)]-68-|", options: [.alignAllCenterX, .alignAllCenterY], metrics: nil, views: ["loginView": toastView])
NSLayoutConstraint.activate([horizontalCenterContraint, widthContraint])
NSLayoutConstraint.activate(verticalContraint)
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: {
toastView.alpha = 1
}, completion: nil)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double((Int64)(2 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: {
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: {
toastView.alpha = 0
}, completion: { finished in
toastView.removeFromSuperview()
})
})
}
}