Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [HL-99,HL-100] Recipe Details <> Header ,Recipe Details <> Ingredients🎨 #104

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
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
65 changes: 61 additions & 4 deletions Healthy.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions Healthy/Classes/Modules/RecipeDetails/RecipeDetailsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import SwiftUI
import UIKit

final class RecipeDetailsHostingController: UIHostingController<RecipeDetailsView> {
init() {
let viewModel = RecipeDetailsViewModel()
let view = RecipeDetailsView(viewModel: viewModel)
super.init(rootView: view)
}

@available(*, unavailable)
required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

struct RecipeDetailsView: View {
@ObservedObject var viewModel: RecipeDetailsViewModel

var body: some View {
ScrollView(.vertical) {
VStack {
RecipeDetailsHeaderView(viewModel: viewModel.headerViewModel)

RecipeDetailsChefView(viewModel: viewModel.chefViewModel)

RecipeDetailsSelectionView(viewModel: viewModel.selectionViewModel)

RecipeDetailsTitleView(viewModel: viewModel.recipesTitleViewModel)

IngredientListView(items: viewModel.ingredientViewModel)
}
.padding()
}
}
}

struct RecipeDetailsView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailsView(viewModel: RecipeDetailsViewModel())
}
}
49 changes: 49 additions & 0 deletions Healthy/Classes/Modules/RecipeDetails/RecipeDetailsViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Foundation

final class RecipeDetailsViewModel: ObservableObject {
var headerViewModel: RecipeDetailsHeaderView.ViewModel {
RecipeDetailsHeaderView.ViewModel(
title: "Spicy chicken burger with French fries",
duration: 20,
reviews: 13, onBookmark: {
print("Did tap bookmark")
}
)
}

var chefViewModel: RecipeDetailsChefView.ViewModel {
RecipeDetailsChefView.ViewModel(chefName: "Laura wilson", location: "Lagos, Nigeria")
}

var selectionViewModel: RecipeDetailsSelectionView.ViewModel {
RecipeDetailsSelectionView.ViewModel(
ingredient: "Ingredient",
procedure: "Procedure")
}

var ingredientViewModel: [IngredientListView.ViewModel] {
[IngredientListView.ViewModel(
ingredientName: "Tomatos",
ingredientImage: "placeholder-tomatos-image",
ingredientQuantity: "500"),
IngredientListView.ViewModel(
ingredientName: "Cabbage",
ingredientImage: "placeholder-cabbage-image",
ingredientQuantity: "300"),
IngredientListView.ViewModel(
ingredientName: "Taco",
ingredientImage: "placeholder-taco-image",
ingredientQuantity: "300"),
IngredientListView.ViewModel(
ingredientName: "Slice Bread",
ingredientImage: "placeholder-slice-image",
ingredientQuantity: "300")
]
}

var recipesTitleViewModel: RecipeDetailsTitleView.ViewModel {
RecipeDetailsTitleView.ViewModel(dishImage: "icon-dish",
serveCount: 1,
itemsCount: 10)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import SwiftUI

extension IngredientListView {
struct ViewModel {
let ingredientName: String
let ingredientImage: String
let ingredientQuantity: String
}
}

extension IngredientListView.ViewModel: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(ingredientName)
hasher.combine(ingredientImage)
hasher.combine(ingredientQuantity)
}
}

struct IngredientListView: View {
let items: [ViewModel]

var body: some View {
ForEach(items, id: \.self) { item in
HStack {
Image(item.ingredientImage)
.resizable()
.frame(width: 52.0, height: 52.0)

Text(item.ingredientName)
.foregroundColor(.black)

Spacer()

Text("\(item.ingredientQuantity) gm")
.foregroundColor(.gray)
}
.padding()
.background(Color(.black20))
.cornerRadius(12.0)
}
}
}

struct IngredientListView_Previews: PreviewProvider {
static var previews: some View {
IngredientListView(
items: [IngredientListView.ViewModel(
ingredientName: "Tomatos",
ingredientImage: "placeholder-tomatos-image",
ingredientQuantity: "500"),
IngredientListView.ViewModel(
ingredientName: "Cabbage",
ingredientImage: "placeholder-cabbage-image",
ingredientQuantity: "300"),
IngredientListView.ViewModel(
ingredientName: "Taco",
ingredientImage: "placeholder-taco-image",
ingredientQuantity: "300"),
IngredientListView.ViewModel(
ingredientName: "Slice Bread",
ingredientImage: "placeholder-slice-image",
ingredientQuantity: "300")
])
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import SwiftUI

extension RecipeDetailsChefView {
struct ViewModel {
let chefName: String
let location: String
}
}

struct RecipeDetailsChefView: View {
let viewModel: ViewModel

var body: some View {
HStack {
Image("image-chef-placeholder")
.resizable()
.frame(width: 40.0, height: 40.0)

VStack(alignment: .leading, spacing: 2.0) {
Text(viewModel.chefName)
.bodyTextStyle()
HStack(spacing: 4.0) {
Image("image-location")
Text(viewModel.location)
}
}

Spacer()

Button("Follow", action: {})
.buttonStyle(PrimaryButtonStyle())
}
}
}

struct RecipeDetailsChefView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailsChefView(
viewModel: RecipeDetailsChefView.ViewModel(
chefName: "Laura wilson",
location: "Lagos, Nigeria"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import SwiftUI

extension RecipeDetailsHeaderView {
struct ViewModel {
let title: String
let duration: Int
let reviews: Int
let onBookmark: () -> Void

var readableDuration: String {
"\(duration) min"
}
var readableReviews: String {
"(\(reviews)k Reviews)"
}
}
}

struct RecipeDetailsHeaderView: View {
let viewModel: ViewModel

var body: some View {
VStack(spacing: 10.0) {
ZStack {

Image("placeholder-recipe-image")
.resizable()
.scaledToFill()
.frame(height: 150.0)

LinearGradient(colors: [
.clear,
.black
],
startPoint: .top,
endPoint: .bottom)

VStack(alignment: .trailing, spacing: 10) {
Spacer()
HStack {
Image("star")
.frame(width: 8, height: 8)

Text("4.0")
.font(Font.custom("Poppins", size: 8))
.multilineTextAlignment(.trailing)
.foregroundColor(.black)

}

.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(Color(red: 1, green: 0.88, blue: 0.7))
.cornerRadius(20)
.padding()
Spacer(minLength: 15)

HStack {
Spacer()

HStack {
Image("icon-timer")
.frame(width: 17, height: 17)

Text(viewModel.readableDuration)
.foregroundColor(.white)

Button(action: viewModel.onBookmark) {
Image(systemName: "bookmark")
}
.padding(4.0)
.background(Color.white)
.cornerRadius(.infinity)
}
.padding()
}
}
}
.frame(height: 150.0)
.clipped()
.cornerRadius(10.0)

HStack(alignment: .top) {
Text(viewModel.title)
.bodyTextStyle()

Spacer()

Text(viewModel.readableReviews)
.foregroundColor(.gray)
}
}
}
}

struct RecipeDetailsHeaderView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailsHeaderView(
viewModel: RecipeDetailsHeaderView.ViewModel(
title: "Spicy chicken burger with French fries",
duration: 20,
reviews: 13, onBookmark: {
print("Did tap bookmark")
}
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import SwiftUI

extension RecipeDetailsSelectionView {
struct ViewModel {
let ingredient: String
let procedure: String
}
}

struct RecipeDetailsSelectionView: View {
let viewModel: ViewModel

@State private var isIngredientSelected = true
var body: some View {
HStack(alignment: .top, spacing: 15.0) {

Button("Ingredient", action: {
isIngredientSelected = true
}).background(isIngredientSelected ? Color(.primary100) : Color(.primary20))
.buttonStyle(SecondaryButtonStyle())
.cornerRadius(10.0)

Button("Procedure", action: {
isIngredientSelected = true
}).background(!isIngredientSelected ? Color(.primary100): Color(.primary20))
.buttonStyle(SecondaryButtonStyletwo())
.cornerRadius(10.0)

}.padding(.horizontal, 30)
.padding(.top, 12)
.padding(.bottom, 13)
.frame(width: 375.0)

}
}

struct RecipeDetailsSelectionView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailsSelectionView(
viewModel: RecipeDetailsSelectionView.ViewModel(
ingredient: "Ingredient",
procedure: "Procedure"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import SwiftUI

extension RecipeDetailsTitleView {
struct ViewModel {
let dishImage: String
let serveCount: Int
let itemsCount: Int
}
}

struct RecipeDetailsTitleView: View {
let viewModel: ViewModel

var body: some View {
HStack {
Image(viewModel.dishImage)
.frame(width: 17.0, height: 17.0)

Text("\(viewModel.serveCount) serve")
.titleTextStyle()

Spacer()

Text("\(viewModel.itemsCount) Items")
.titleTextStyle()

}.padding()
}
}

struct RecipeDetailsTitleView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailsTitleView(viewModel: RecipeDetailsTitleView.ViewModel(
dishImage: "icon-dish",
serveCount: 1,
itemsCount: 10))
}
}
Loading