Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Foundation

protocol ContactUSServiceProtocol {
func fetch() async throws -> Data
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetch what?
usa um nome mais claro

func send(with parameters: [String: String]) async throws
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

send what?
usar um nome mais claro tb

}

final class ContactUSService: ContactUSServiceProtocol {
func fetch() async throws -> Data {
return try await withCheckedThrowingContinuation { continuation in
AF.shared.request(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ja chegou na parte de parar de usar singleton?
se sim, usar GoodNetworkLayer aqui tb
se n me engano o Jorge tem um PR em q ele usou

se n tiver chegado na parte de remover singlton, pode ignorar

Endpoints.contactUs,
method: .get,
parameters: nil,
headers: nil
) { result in
switch result {
case .success(let data):
continuation.resume(returning: data)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}

func send(with parameters: [String: String]) async throws {
return try await withCheckedThrowingContinuation { continuation in
AF.shared.request(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mesmo comentario acima

Endpoints.sendMessage,
method: .post,
parameters: parameters,
headers: nil
) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
}
211 changes: 211 additions & 0 deletions CleanCodeApp/Modules/Features/Luz/ContactsUs/ContactUSView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import UIKit

final class ContactUSView: UIView {
let symbolConfiguration = UIImage.SymbolConfiguration(pointSize: 36)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tem propriedade com essa e outras que poderiam ser privates


lazy var textView: UITextView = {
let text = UITextView()
text.text = "Escreva sua mensagem aqui"
text.translatesAutoresizingMaskIntoConstraints = false
return text
}()

lazy var titleLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.font = UIFont.systemFont(ofSize: 24, weight: .semibold)
label.text = "Escolha o canal para contato"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

lazy var messageLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
label.text = "Ou envie uma mensagem"
label.numberOfLines = 2
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

// MARK: - UIButton's
lazy var phoneButton: UIButton = {
let button = UIButton()
button.backgroundColor = .systemGray4
button.layer.cornerRadius = 10
button.setImage(
.init(systemName: "phone")?.withConfiguration(symbolConfiguration),
for: .normal
)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

lazy var emailButton: UIButton = {
let button = UIButton()
button.backgroundColor = .systemGray4
button.layer.cornerRadius = 10
button.setImage(
.init(systemName: "envelope")?.withConfiguration(symbolConfiguration),
for: .normal
)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

lazy var chatButton: UIButton = {
let button = UIButton()
button.backgroundColor = .systemGray4
button.layer.cornerRadius = 10
button.setImage(
.init(systemName: "message")?.withConfiguration(symbolConfiguration),
for: .normal
)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

lazy var sendMessageButton: UIButton = {
let button = UIButton()
button.backgroundColor = .blue
button.setTitle("Enviar", for: .normal)
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 10
button.setContentHuggingPriority(.required, for: .horizontal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

lazy var closeButton: UIButton = {
let button = UIButton()
button.setTitle("Voltar", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.backgroundColor = .clear
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.blue.cgColor
button.layer.cornerRadius = 10
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .systemGray6
configureUI()
setupLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func configureUI() {
[
titleLabel,
phoneButton,
emailButton,
chatButton,
messageLabel,
textView,
sendMessageButton,
closeButton
].forEach { addSubview($0) }
}

func setupLayout() {
let contactButtonsStackView = createContactButtonsStackView()
let messageStackView = createMessageStackView()
let ctaStackView = createCTAStackView()

let mainStackView = UIStackView(
arrangedSubviews: [
titleLabel,
contactButtonsStackView,
messageStackView,
ctaStackView
]
)
mainStackView.axis = .vertical
mainStackView.spacing = 30
mainStackView.translatesAutoresizingMaskIntoConstraints = false

addSubview(mainStackView)

setupConstraints(for: mainStackView)
}

func setupConstraints(for mainStackView: UIStackView) {
NSLayoutConstraint.activate(
[
mainStackView.topAnchor.constraint(
equalTo: safeAreaLayoutGuide.topAnchor,
constant: 30
),
mainStackView.leadingAnchor.constraint(
equalTo: safeAreaLayoutGuide.leadingAnchor,
constant: 20
),
mainStackView.trailingAnchor.constraint(
equalTo: safeAreaLayoutGuide.trailingAnchor,
constant: -20
),
mainStackView.bottomAnchor.constraint(
equalTo: safeAreaLayoutGuide.bottomAnchor,
constant: -20
)
]
)
}
}

private extension ContactUSView {
func createContactButtonsStackView() -> UIStackView {
let stackView = UIStackView(
arrangedSubviews: [
phoneButton,
emailButton,
chatButton
]
)
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .equalSpacing

[phoneButton, emailButton, chatButton].forEach { view in
view.widthAnchor.constraint(equalToConstant: 80).isActive = true
view.heightAnchor.constraint(equalToConstant: 80).isActive = true
}

return stackView
}

func createMessageStackView() -> UIStackView {
let stackView = UIStackView(
arrangedSubviews: [
messageLabel,
textView
]
)
stackView.axis = .vertical
stackView.spacing = 20
return stackView
}

func createCTAStackView() -> UIStackView {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oq é CTA?
lembre que não é bom usar siglas (há raras exceções)

let stackView = UIStackView(
arrangedSubviews: [
sendMessageButton,
closeButton
]
)
stackView.axis = .vertical
stackView.spacing = 20

[sendMessageButton, closeButton].forEach { view in
view.heightAnchor.constraint(equalToConstant: 40).isActive = true
}
return stackView
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Foundation

final class LuzContactUSViewModel {
var model: ContactUsModel?
private let serivce: ContactUSServiceProtocol

init(serivce: ContactUSServiceProtocol) {
self.serivce = serivce
}

func fetch() async throws {
guard let data = try? await serivce.fetch() else { return }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dar uma nome melhor para fetch
nao usar try? opcional, já que a funcao dispara erro

fazer protocol para viewModel (se estiver no contexto desse PR)

let model = try? JSONDecoder().decode(ContactUsModel.self, from: data)
self.model = model
}

func send(parameters: [String: String]) async throws {
try? await serivce.send(with: parameters)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

melhorar nome e remover try opcional

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UIKit

enum LuzContactUsFactory {
static func make() -> UIViewController {
let service = ContactUSService()
let viewModel = LuzContactUSViewModel(serivce: service)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

service*

return LuzContactUsViewController(viewModel: viewModel)
}
}
Loading