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: Add review product screen ⭐ #119

Open
wants to merge 42 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
be508ce
feat: add review products files
MarwaEbrahem Aug 18, 2022
82285fe
Squashed commit of the following:
MarwaEbrahem Aug 18, 2022
99fe79b
feat: Add review product UI and navigation bar
MarwaEbrahem Aug 19, 2022
accade5
Merge branch 'develop' into review-screen
MarwaEbrahem Aug 19, 2022
d13867b
fix: fix ReviewProductNavigationBarBehavior file target
MarwaEbrahem Aug 19, 2022
9e559c8
fix: fix ReviewerTableViewCell file target
MarwaEbrahem Aug 19, 2022
0083737
fix: files target
MarwaEbrahem Aug 19, 2022
9577ef3
generate back image
MarwaEbrahem Aug 22, 2022
661dfaf
feat: Add mock product reviews files
MarwaEbrahem Aug 23, 2022
404f2b2
feat: apply clean architecture to get review data from network to app…
MarwaEbrahem Aug 24, 2022
7b08f4f
feat: update review cell with data
MarwaEbrahem Aug 24, 2022
b2b8617
feat: add skeleton view to review product screen
MarwaEbrahem Aug 25, 2022
d3815be
fix: make height of table view cell dynamic to wrap content
MarwaEbrahem Aug 25, 2022
8a8be4c
feat: Add error alert
MarwaEbrahem Aug 25, 2022
983ec6a
fix: edit naming convention
MarwaEbrahem Aug 25, 2022
05067f0
fix: edit ui constrains
MarwaEbrahem Aug 26, 2022
668c4bf
fix: edit access level of UIAlertContoroller+Builder to public
MarwaEbrahem Aug 26, 2022
825feb3
fix: Split review product view to subviews
MarwaEbrahem Aug 26, 2022
d0b6d77
fix: enhance bind between reviewProduct view controller and view model
MarwaEbrahem Aug 30, 2022
9d79d2a
fix: bind data between review product and rating details
MarwaEbrahem Aug 31, 2022
19626e5
fix: edit toDomain function
MarwaEbrahem Sep 1, 2022
2d17bf1
fix: change codable to decodable in model
MarwaEbrahem Sep 1, 2022
daadc30
Update Reviews init function style
MarwaEbrahem Sep 1, 2022
745ba58
fix: edit processFetchedReviews function
MarwaEbrahem Sep 1, 2022
f2d4324
fix: Update initialize of reviewList variable
MarwaEbrahem Sep 1, 2022
083d01f
fix: Update initialize of cellViewModels variable
MarwaEbrahem Sep 1, 2022
29e0f85
fix: Update initialize of alertMessage variable
MarwaEbrahem Sep 1, 2022
b4c4601
fix: Update initialize of navBarRating variable
MarwaEbrahem Sep 1, 2022
564f14d
Update Dokan/Dokan/Scenes/ReviewProduct/ReviewProductNavigationBarBeh…
MarwaEbrahem Sep 1, 2022
d89c97e
fix: update state enum name
MarwaEbrahem Sep 1, 2022
399858c
fix: update code
MarwaEbrahem Sep 3, 2022
2bcbcfd
fix: Update ReviewerTableViewCell
MarwaEbrahem Sep 4, 2022
20af4f0
fix: refactor RatingDetailsViewModel
MarwaEbrahem Sep 4, 2022
2e171d1
fix: refactor ReviewProductNavigationBarBehavior
MarwaEbrahem Sep 4, 2022
40d4b73
fix: update register ReviewerTableViewCell
MarwaEbrahem Sep 4, 2022
fa079d7
fix: refactor MockNetwork
MarwaEbrahem Sep 4, 2022
03a6d5f
Squashed commit of the following:
MarwaEbrahem Sep 4, 2022
a16934e
feat: solve merge conflict
MarwaEbrahem Sep 4, 2022
48904c6
fix: setup view by using uiviewfromnib file
MarwaEbrahem Sep 4, 2022
fb44a8b
Merge branch 'develop' into review-screen
MarwaEbrahem Sep 5, 2022
63eb160
feat: Add unit test to review product files (#122)
MarwaEbrahem Sep 5, 2022
b8afd36
fix: fix import module in test files
MarwaEbrahem Sep 5, 2022
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
30 changes: 30 additions & 0 deletions Core/Sources/Core/Models/DomainConvertible/Reviews.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// File.swift
//
//
// Created by marwa on 23/08/2022.
//

import Domain
import Networking

extension Networking.Reviews: DomainConvertible {

func toDomain() -> Domain.Reviews {
return Domain.Reviews(rating: rating,
totalRatingNumber: totalRatingNumber,
fiveStarRatingNumber: fiveStarRatingNumber,
fourStarRatingNumber: fourStarRatingNumber,
threeStarRatingNumber: threeStarRatingNumber,
twoStarRatingNumber: twoStarRatingNumber,
oneStarRatingNumber: oneStarRatingNumber,
reviews: reviews.map { $0.toDomain() })
}
}

extension Networking.Review: DomainConvertible {

func toDomain() -> Domain.Review {
return Domain.Review(image: image, name: name, date: date, rating: rating, reviewDescription: reviewDescription)
}
}
33 changes: 33 additions & 0 deletions Core/Sources/Core/Repository/ReviewsRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// File.swift
//
//
// Created by marwa on 23/08/2022.
//

import Domain
import Foundation
import Networking

/// Implementation of `Domain.ReviewsRepository`
///
struct ReviewsRepository: Domain.ReviewsRepository {

let remote: ReviewsRemoteProtocol

init(remote: ReviewsRemoteProtocol) {
self.remote = remote
}

func loadReviews(completion: @escaping (Result<Domain.Reviews, Error>) -> Void) {
remote.loadReviewProductData { result in
switch result {
case let .success(productReviews):
let convertedReviews = productReviews.toDomain()
completion(.success(convertedReviews))
case let .failure(error):
completion(.failure(error))
}
}
}
}
5 changes: 5 additions & 0 deletions Core/Sources/Core/Tools/RepositoryProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public struct DefaultRepositoryProvider {

extension DefaultRepositoryProvider: RepositoryProvider {

public func makeReviewsRepository() -> Domain.ReviewsRepository {
let remote = MockNetwork()
return ReviewsRepository(remote: remote)
}

public func makeProductRepository() -> Domain.ProductRepository {
let remote = ProductsRemote(network: network)
return ProductRepository(remote: remote)
Expand Down
117 changes: 116 additions & 1 deletion Dokan/Dokan.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions Dokan/Dokan/Assets.xcassets/left.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "left-2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,43 @@
//
// Created by raniazeid on 28/07/2022.
//

import Domain
import UIDokan
import UIKit

class ReviewerTableViewCell: UITableViewCell {
// MARK: - Outlets
class ReviewerTableViewCell: UITableViewCell, IdentifiableView {

@IBOutlet private(set) weak var reviewerImageView: UIImageView!
@IBOutlet private(set) weak var reviewerNameLabel: UILabel!
@IBOutlet private(set) weak var reviewerComment: UITextView!
// MARK: - Outlets

// MARK: Lifecycle
@IBOutlet private weak var reviewerImageView: UIImageView!
@IBOutlet private weak var reviewerNameLabel: UILabel!
@IBOutlet weak var reviewerComment: UILabel!
@IBOutlet weak var ratingStarsView: StarsView!

// MARK: Lifecycle
// MARK: - life cycle..

override func awakeFromNib() {
super.awakeFromNib()
reviewerImageView.applyCircleImageStyle()
}

// MARK: Cell Configurations
// MARK: - method to configure cell

func configureCell(viewModel: ViewModel) {
reviewerNameLabel.text = viewModel.name
reviewerComment.text = viewModel.comment
func configureCell(viewModel: ReviewerCellViewModel) {
reviewerImageView.setImage(with: viewModel.reviewerImageUrl, placeholderImage: .star)
reviewerNameLabel.text = viewModel.reviewerName
reviewerComment.text = viewModel.reviewerComment
ratingStarsView.applyStyleToView()
ratingStarsView.updateStarsRating(viewModel.rating)
}
}

// MARK: View Model

extension ReviewerTableViewCell {
// MARK: - View Model

struct ViewModel {
var imageUrl: String
var name: String
var comment: String
struct ReviewerCellViewModel {
let reviewerImageUrl: String
let reviewerName: String
let reviewerComment: String
let rating: Double
}
}
117 changes: 76 additions & 41 deletions Dokan/Dokan/Scenes/ProductDetails/Cell/ReviewerTableViewCell.xib
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand All @@ -18,74 +18,109 @@
<rect key="frame" x="0.0" y="0.0" width="420" height="187"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t5f-TZ-ful">
<rect key="frame" x="0.0" y="0.0" width="420" height="187"/>
<stackView opaque="NO" contentMode="scaleToFill" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="K5h-Jv-2I6">
<rect key="frame" x="0.0" y="0.0" width="420" height="167"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="aMW-WS-Xdx">
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="9pv-7I-Y3B"/>
<constraint firstAttribute="height" constant="40" id="IV1-Jx-3gu"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="Kdx-d7-l6N">
<rect key="frame" x="55" y="0.0" width="365" height="187"/>
<stackView opaque="NO" contentMode="scaleToFill" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="FDB-Wn-BUo">
<rect key="frame" x="0.0" y="0.0" width="40" height="167"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="5ua-2S-dtm">
<rect key="frame" x="0.0" y="0.0" width="365" height="17"/>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="aMW-WS-Xdx">
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="9pv-7I-Y3B"/>
<constraint firstAttribute="height" constant="40" id="IV1-Jx-3gu"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
</subviews>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Kdx-d7-l6N">
<rect key="frame" x="50" y="0.0" width="370" height="167"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="5ua-2S-dtm">
<rect key="frame" x="0.0" y="0.0" width="370" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Peter Parker" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5WL-vR-UeQ">
<rect key="frame" x="0.0" y="0.0" width="182.5" height="17"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="20"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2 Bulan yang lalu" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="lGD-ya-DVc">
<rect key="frame" x="182.5" y="0.0" width="182.5" height="17"/>
<rect key="frame" x="274" y="0.0" width="96" height="20"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" systemColor="systemGrayColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="20" id="wNg-iy-czn"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZSV-Vh-XjP">
<rect key="frame" x="0.0" y="17" width="365" height="14"/>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZSV-Vh-XjP" customClass="StarsView" customModule="UIDokan">
<rect key="frame" x="0.0" y="67.5" width="370" height="20"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="HN5-Tz-hNY"/>
<constraint firstAttribute="height" constant="20" id="HN5-Tz-hNY"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." translatesAutoresizingMaskIntoConstraints="NO" id="8ne-qC-Ucn">
<rect key="frame" x="0.0" y="31" width="365" height="156"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="textColor" systemColor="labelColor"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="ZaW-Ej-lig">
<rect key="frame" x="0.0" y="135" width="370" height="32"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="32" id="mcj-id-nTs"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="Kdx-d7-l6N" firstAttribute="leading" secondItem="aMW-WS-Xdx" secondAttribute="trailing" constant="15" id="3It-wm-mrM"/>
<constraint firstItem="aMW-WS-Xdx" firstAttribute="leading" secondItem="t5f-TZ-ful" secondAttribute="leading" id="83i-dC-ryb"/>
<constraint firstItem="aMW-WS-Xdx" firstAttribute="top" secondItem="t5f-TZ-ful" secondAttribute="top" id="Rif-Ug-GO8"/>
<constraint firstItem="Kdx-d7-l6N" firstAttribute="top" secondItem="t5f-TZ-ful" secondAttribute="top" id="V3L-fg-Go7"/>
<constraint firstAttribute="bottom" secondItem="Kdx-d7-l6N" secondAttribute="bottom" id="ZVM-ro-5KR"/>
<constraint firstAttribute="trailing" secondItem="Kdx-d7-l6N" secondAttribute="trailing" id="vlw-56-prQ"/>
</constraints>
</view>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="t5f-TZ-ful" secondAttribute="bottom" id="2Yb-kY-pbC"/>
<constraint firstItem="t5f-TZ-ful" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="I1e-vl-txk"/>
<constraint firstAttribute="trailing" secondItem="t5f-TZ-ful" secondAttribute="trailing" id="UIB-8n-QIe"/>
<constraint firstItem="t5f-TZ-ful" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="rvi-3j-SPx"/>
<constraint firstItem="K5h-Jv-2I6" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="ULJ-pJ-Ng9"/>
<constraint firstAttribute="bottom" secondItem="K5h-Jv-2I6" secondAttribute="bottom" constant="20" id="drv-NE-Lz0"/>
<constraint firstItem="K5h-Jv-2I6" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="uEx-At-wgG"/>
<constraint firstAttribute="trailing" secondItem="K5h-Jv-2I6" secondAttribute="trailing" id="uhT-yI-UwT"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="reviewerComment" destination="8ne-qC-Ucn" id="aUg-Lm-RTS"/>
<outlet property="ratingStarsView" destination="ZSV-Vh-XjP" id="N3g-Xr-waP"/>
<outlet property="reviewerComment" destination="ZaW-Ej-lig" id="oks-zq-Xz2"/>
<outlet property="reviewerImageView" destination="aMW-WS-Xdx" id="b9i-WD-FR9"/>
<outlet property="reviewerNameLabel" destination="5WL-vR-UeQ" id="1sf-yD-KH6"/>
</connections>
Expand Down
Loading