Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,33 @@ struct AnalyticsHubView: View {
VStack(spacing: 0) {
Divider()

Text("Placeholder For Revenue Card")
.padding(.leading)
.frame(maxWidth: .infinity, minHeight: 220, alignment: .leading)
.background(Color(uiColor: .listForeground))
AnalyticsReportCard(title: "REVENUE",
leadingTitle: "Total Sales",
leadingValue: "$3.234",
leadingGrowth: "+23%",
leadingGrowthColor: .withColorStudio(.green, shade: .shade50),
trailingTitle: "Net Sales",
trailingValue: "$2.324",
trailingGrowth: "-4%",
trailingGrowthColor: .withColorStudio(.red, shade: .shade40))
.background(Color(uiColor: .listForeground))

Divider()
}

VStack(spacing: 0) {
Divider()

Text("Placeholder For Orders Card")
.padding(.leading)
.frame(maxWidth: .infinity, minHeight: 220, alignment: .leading)
.background(Color(uiColor: .listForeground))
AnalyticsReportCard(title: "ORDERS",
leadingTitle: "Total Orders",
leadingValue: "145",
leadingGrowth: "+36%",
leadingGrowthColor: .withColorStudio(.green, shade: .shade50),
trailingTitle: "Average Order Value",
trailingValue: "$57,99",
trailingGrowth: "-16%",
trailingGrowthColor: .withColorStudio(.red, shade: .shade40))
.background(Color(uiColor: .listForeground))

Divider()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import SwiftUI

/// Resuable report card made for the Analytics Hub.
///
struct AnalyticsReportCard: View {

let title: String
let leadingTitle: String
let leadingValue: String
let leadingGrowth: String
let leadingGrowthColor: UIColor
let trailingTitle: String
let trailingValue: String
let trailingGrowth: String
let trailingGrowthColor: UIColor

var body: some View {
VStack(alignment: .leading, spacing: Layout.titleSpacing) {

Text(title)
.foregroundColor(Color(.text))
.footnoteStyle()

HStack {

/// Leading Column
///
VStack(alignment: .leading, spacing: Layout.salesColumnSpacing) {

Text(leadingTitle)
.calloutStyle()

Text(leadingValue)
.titleStyle()

GrowthTag(value: leadingGrowth, backgroundColor: leadingGrowthColor)

}
.frame(maxWidth: .infinity, alignment: .leading)

/// Net Sales
///
VStack(alignment: .leading, spacing: Layout.salesColumnSpacing) {
Text(trailingTitle)
.calloutStyle()

Text(trailingValue)
.titleStyle()

GrowthTag(value: trailingGrowth, backgroundColor: trailingGrowthColor)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.padding(Layout.cardPadding)
}
}

private struct GrowthTag: View {

let value: String
let backgroundColor: UIColor

var body: some View {
Text(value)
.padding(AnalyticsReportCard.Layout.growthBackgroundPadding)
.foregroundColor(Color(.textInverted))
.captionStyle()
.background(Color(backgroundColor))
.cornerRadius(AnalyticsReportCard.Layout.growthCornerRadius)
}
}

// MARK: Constants
private extension AnalyticsReportCard {
enum Layout {
static let titleSpacing: CGFloat = 24
static let cardPadding: CGFloat = 16
static let salesColumnSpacing: CGFloat = 10
static let growthBackgroundPadding = EdgeInsets(top: 2, leading: 8, bottom: 2, trailing: 8)
static let growthCornerRadius: CGFloat = 4.0
}
}

// MARK: Previews
struct Previews: PreviewProvider {
static var previews: some View {
AnalyticsReportCard(title: "REVENUE",
leadingTitle: "Total Sales",
leadingValue: "$3.678",
leadingGrowth: "+23%",
leadingGrowthColor: .withColorStudio(.green, shade: .shade40),
trailingTitle: "Net Sales",
trailingValue: "$3.232",
trailingGrowth: "-3%",
trailingGrowthColor: .withColorStudio(.red, shade: .shade40))
.previewLayout(.sizeThatFits)
}
}
4 changes: 4 additions & 0 deletions WooCommerce/WooCommerce.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@
263E38472641FF3400260D3B /* Codegen in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 263E38452641FF3400260D3B /* Codegen */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
263EB409242C58EA00F3A15F /* ProductFormActionsFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263EB408242C58EA00F3A15F /* ProductFormActionsFactoryTests.swift */; };
2647F7B529280A7F00D59FDF /* AnalyticsHubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2647F7B429280A7F00D59FDF /* AnalyticsHubView.swift */; };
2647F7BA292BE2F900D59FDF /* StatsCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2647F7B9292BE2F900D59FDF /* StatsCard.swift */; };
265284022624937600F91BA1 /* AddOnCrossreferenceUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265284012624937600F91BA1 /* AddOnCrossreferenceUseCase.swift */; };
265284092624ACE900F91BA1 /* AddOnCrossreferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265284082624ACE900F91BA1 /* AddOnCrossreferenceTests.swift */; };
2655905B27863D1300BB8457 /* MockCollectOrderPaymentUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2655905A27863D1300BB8457 /* MockCollectOrderPaymentUseCase.swift */; };
Expand Down Expand Up @@ -2522,6 +2523,7 @@
26309F16277D0AEA0012797F /* SafeAreaInsetsKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeAreaInsetsKey.swift; sourceTree = "<group>"; };
263EB408242C58EA00F3A15F /* ProductFormActionsFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFormActionsFactoryTests.swift; sourceTree = "<group>"; };
2647F7B429280A7F00D59FDF /* AnalyticsHubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsHubView.swift; sourceTree = "<group>"; };
2647F7B9292BE2F900D59FDF /* StatsCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsCard.swift; sourceTree = "<group>"; };
265284012624937600F91BA1 /* AddOnCrossreferenceUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOnCrossreferenceUseCase.swift; sourceTree = "<group>"; };
265284082624ACE900F91BA1 /* AddOnCrossreferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOnCrossreferenceTests.swift; sourceTree = "<group>"; };
2655905A27863D1300BB8457 /* MockCollectOrderPaymentUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCollectOrderPaymentUseCase.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5237,6 +5239,7 @@
isa = PBXGroup;
children = (
2647F7B429280A7F00D59FDF /* AnalyticsHubView.swift */,
2647F7B9292BE2F900D59FDF /* StatsCard.swift */,
);
path = "Analytics Hub";
sourceTree = "<group>";
Expand Down Expand Up @@ -10170,6 +10173,7 @@
02482A8B237BE8C7007E73ED /* LinkSettingsViewController.swift in Sources */,
CE227097228F152400C0626C /* WooBasicTableViewCell.swift in Sources */,
02C27BCE282CB52F0065471A /* CardPresentPaymentReceiptEmailCoordinator.swift in Sources */,
2647F7BA292BE2F900D59FDF /* StatsCard.swift in Sources */,
451526392577D89E0076B03C /* AddAttributeViewModel.swift in Sources */,
DE0A2EAF281BA278007A8015 /* ProductCategorySelectorViewModel.swift in Sources */,
45B9C64323A91CB6007FC4C5 /* PriceInputFormatter.swift in Sources */,
Expand Down
24 changes: 24 additions & 0 deletions WooFoundation/WooFoundation/ViewModifiers/WooStyleModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ public struct FootnoteStyle: ViewModifier {
}
}

public struct CalloutStyle: ViewModifier {
public func body(content: Content) -> some View {
content
.font(.callout)
.foregroundColor(Color(.textSubtle))
}
}

public struct CaptionStyle: ViewModifier {
public func body(content: Content) -> some View {
content
.font(.caption)
.foregroundColor(Color(.text))
}
}

public struct ErrorStyle: ViewModifier {
public func body(content: Content) -> some View {
content
Expand Down Expand Up @@ -201,4 +217,12 @@ public extension View {
func headlineLinkStyle() -> some View {
self.modifier(HeadlineLinkStyle())
}

func calloutStyle() -> some View {
self.modifier(CalloutStyle())
}

func captionStyle() -> some View {
self.modifier(CaptionStyle())
}
}