Sales Dashboard

Sales Dashboard

by dockui

A modern SwiftUI sales dashboard UI, a line chart, and recent orders. Clean layout, with smooth gradients.

Platform
SwiftUI
Code
Native Swift
Format
Screen
Access
Free

Code Snippet

import SwiftUI

struct SalesDashboardTemplate: View {
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 32) {
                    // KPI Tiles
                    SalesKPITiles()
                        .padding(.top, 16)

                    // Sales Trend Chart
                    VStack(alignment: .leading, spacing: 16) {
                        Text("Sales Trend")
                            .font(.headline)
                            .padding(.horizontal)
                        SalesLineChartView(data: salesTrendData)
                            .frame(height: 160)
                            .padding(.horizontal)
                    }

                    // Recent Orders
                    VStack(alignment: .leading, spacing: 16) {
                        Text("Recent Orders")
                            .font(.headline)
                            .padding(.horizontal)
                        VStack(spacing: 12) {
                            ForEach(recentOrders) { order in
                                SalesOrderRow(order: order)
                            }
                        }
                        .padding(.horizontal)
                    }
                }
                .padding(.bottom, 32)
            }
            .navigationTitle("Sales Dashboard")
            .background(
                LinearGradient(gradient: Gradient(colors: [Color.blue.opacity(0.14), Color.purple.opacity(0.10)]), startPoint: .top, endPoint: .bottom)
                    .ignoresSafeArea()
            )
        }
    }
}

// MARK: - KPI Tiles
struct SalesKPITiles: View {
    let stats: [(icon: String, title: String, value: String, color: Color)] = [
        ("dollarsign.circle.fill", "Revenue", "$12,400", .blue),
        ("cart.fill", "Orders", "320", .green),
        ("person.2.fill", "Customers", "210", .purple)
    ]
    var body: some View {
        LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 16) {
            ForEach(0..<stats.count, id: \.self) { i in
                let stat = stats[i]
                VStack(spacing: 10) {
                    ZStack {
                        Circle()
                            .fill(stat.color.opacity(0.15))
                            .frame(width: 40, height: 40)
                        Image(systemName: stat.icon)
                            .foregroundColor(stat.color)
                            .font(.title2)
                    }
                    Text(stat.title)
                        .font(.caption)
                        .foregroundColor(.secondary)
                    Text(stat.value)
                        .font(.headline)
                        .fontWeight(.semibold)
                        .foregroundColor(.primary)
                }
                .padding()
                .frame(maxWidth: .infinity)
                .background(Color(.systemBackground).opacity(0.7)    )            .cornerRadius(16)
                .shadow(color: Color.black.opacity(0.04), radius: 6, x: 0, y: 2)
            }
        }
        .padding(.horizontal)
    }
}

// MARK: - Sales Trend Line Chart (Dummy)
struct SalesLineChartView: View {
    let data: [Double]
    var body: some View {
        GeometryReader { geo in
            let maxY = (data.max() ?? 1)
            let minY = (data.min() ?? 0)
            let height = geo.size.height
            let width = geo.size.width
            let stepX = width / CGFloat(data.count - 1)
            Path { path in
                for i in data.indices {
                    let x = CGFloat(i) * stepX
                    let y = height - ((CGFloat(data[i] - minY) / CGFloat(maxY - minY)) * height)
                    if i == 0 {
                        path.move(to: CGPoint(x: x, y: y))
                    } else {
                        path.addLine(to: CGPoint(x: x, y: y))
                    }
                }
            }
            .stroke(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.purple]), startPoint: .leading, endPoint: .trailing), lineWidth: 3)
            .shadow(color: Color.blue.opacity(0.18), radius: 6, x: 0, y: 4)
        }
        .background(
            RoundedRectangle(cornerRadius: 16, style: .continuous)
                .fill(Color(.systemBackground).opacity(0.7))
        )
    }
}

let salesTrendData: [Double] = [8, 10, 7, 12, 14, 13, 15, 18, 16, 20, 22, 19, 23, 25]

// MARK: - Recent Orders
struct SalesOrder: Identifiable {
    let id = UUID()
    let customer: String
    let date: String
    let amount: String
    let status: String
}

let recentOrders: [SalesOrder] = [
    .init(customer: "Alice Smith", date: "May 27", amount: "$120.00", status: "Completed"),
    .init(customer: "Bob Lee", date: "May 27", amount: "$89.99", status: "Pending"),
    .init(customer: "Charlie Kim", date: "May 26", amount: "$240.50", status: "Completed"),
    .init(customer: "Dana Fox", date: "May 25", amount: "$59.00", status: "Refunded")
]

struct SalesOrderRow: View {
    let order: SalesOrder
    var statusColor: Color {
        switch order.status {
        case "Completed": return .green
        case "Pending": return .orange
        case "Refunded": return .red
        default: return .gray
        }
    }
    var body: some View {
        HStack(spacing: 16) {
            VStack(alignment: .leading, spacing: 4) {
                Text(order.customer)
                    .font(.headline)
                Text(order.date)
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
            Spacer()
            Text(order.amount)
                .font(.headline)
            Text(order.status)
                .font(.caption)
                .fontWeight(.semibold)
                .foregroundColor(.white)
                .padding(.vertical, 4)
                .padding(.horizontal, 10)
                .background(statusColor)
                .cornerRadius(8)
        }
        .padding(.vertical, 8)
        .padding(.horizontal, 12)
        .background(
            RoundedRectangle(cornerRadius: 14, style: .continuous)
                .fill(Color(.systemBackground).opacity(0.7))
        )
    }
}

More Templates

Similar Blogs

View All Articles
How to Translate Xcode String Catalogs with AI

How to Translate Xcode String Catalogs with AI

Learn how to efficiently translate Xcode string catalogs using AI fast, streamlining localization for your iOS and SwiftUI applications.

by dockui
May 4
How to optimize your SwiftUI app in 2026

How to optimize your SwiftUI app in 2026

Discover top strategies to optimize your SwiftUI app in 2026, enhancing performance, responsiveness, and maintainability with modern concurrency.

by dockui
Apr 29
SwiftUI: iOS Confirmation Alert (Confirm + Cancel)

SwiftUI: iOS Confirmation Alert (Confirm + Cancel)

SwiftUI iOS confirmation alert with Confirm and Cancel buttons. Beginners guide to building safe actions, destructive deletes, and commit dialogs.

by dockui
Nov 11
SwiftUI: IOS Haptic Feedback Guide 2026

SwiftUI: IOS Haptic Feedback Guide 2026

Add click to vibrate haptic feedback in SwiftUI. Full guide to UIImpactFeedbackgenerator, success, error, selection, and tap vibration patterns with code.

by dockui
Nov 11

Code copied to clipboard!