Roasting Plant

Ordering from a Detroit Coffee Favorite.

Overview

Ordering from a Detroit Coffee Favorite.

Roasting Plant is a mobile ordering app for a local Detroit coffee shop, built entirely in SwiftUI. Users browse the menu, customize their drink, pick size, milk, sugar, iced, and add it to a multi-item cart with itemized pricing and tax. I built this as my first solo iOS project.

Highlights

  • 5 connected views sharing state through SwiftUI's binding
  • Size based pricing, alternative milk upcharges, iced upcharges, and tax calculated in the Coffee model
  • Full order flow from browsing to placing an order

Tech Stack

  • SwiftUI

Team: Solo

Role: iOS Developer, UI/UX Designer

Timeline: Oct 2025 - Oct 2025

Challenges & Solutions

01

Syncing Drink Data Across Views

Challenge: The app has three screens that all need the same drink data. Changes on one screen had to persist everywhere else without being changed.

Solution: Used @State as the main data point and passed data through views with @Binding. The Coffee struct holds all customization options, orderedCoffees array keeps track of the users ordered drinks.

Result: Adding a drink, confirming it in the sheet, and seeing it in the cart all works together as one shared array.

02

Pricing with Multiple Variables

Challenge: Each drink's price changes based on size, milk type, and whether it's iced. The cart has to show individual prices, upcharges, subtotal, and tax, and all of it needs to stay accurate as users add and remove drinks.

Solution:
Put the pricing logic inside the Coffee struct so each part of the price has its own function. The cart adds everything by looping through the array to get a subtotal and total.

Result: Prices calculate every time a drink is added or removed, so the subtotal, tax, and total in the cart always match what the user actually ordered.

Screenshots

Import Source screen

Order Menu

Browse espresso and drip coffee options with a search bar to find drinks fast.

Import Source screen

Drink Customization

Pick your size, milk type, sugar, and iced preference, then add it to your cart.

Import Source screen

Cart & Checkout

Review your order with itemized pricing and tax before placing it.

What I Built

  • Drink customization flow with size, milk type, sugar, iced/hot, special requests, and name tied to a single Coffee model with real price calculations
  • Multi-drink cart with swipe-to-delete and live itemized pricing including subtotal, tax, and total
  • Order confirmation sheet that lets users review each drink before adding it to the cart

Code Snippets

Placeholder intro copy for the code section. Replace this with the most interesting Roasting Plant implementation details.

Drink Price Calculation

Drink prices are calculated based on size, milk selection, and whether the drink is iced, each modifier adjusts the final cost.

func basePrice() -> Double {
    var price = size.basePrice
    if iced == true {
        price += 0.5
    }
    return price
}

func calculateDrinkPrice() -> Double {
    var price = size.basePrice
    if milkType == .Oat { price += 0.65 }
    if milkType == .Soy { price += 0.75 }
    if milkType == .Almond { price += 0.5 }
    if milkType == .Whole { price += 0 }
    return price
}

Cart Swipe Action

Displays each ordered coffee in a list with swipe-to-delete. Swiping left reveals a delete button that removes that drink from the cart.

ForEach(orderedCoffees, id: \.self) { coffee in
    HStack {
        // drink detail code...
    }
    .swipeActions(allowsFullSwipe: true) {
        Button(role: .destructive) {
            if let index = orderedCoffees.firstIndex(where: {
                $0.name == coffee.name && $0.assetName == coffee.assetName
            }) {
                orderedCoffees.remove(at: index)
            }
        } label: {
            Label("Delete", systemImage: "trash")
        }
    }
}

Next Iterations

Next I'd add user accounts so people can save their recent orders and reorder with one tap instead of rebuilding from scratch. I'd also add a live order status screen so users know when their drink is received, brewing, or ready for pickup. A simple rewards system to track purchases and earn points toward free drinks would give users a reason to keep coming back.

Outcome

My first solo iOS project from start to finish. I went from an empty Xcode project to a fully functional ordering flow with menu browsing, drink customization, order confirmation, and a multi-item cart with real pricing. This is where I learned how SwiftUI's state management works. Passing data between views with @State and @Binding, structuring a model to handle pricing logic, building UI that feels like a real product.

More Case Studies