Siren Cafe — Menu Browsing & Customer Engagement
A SwiftUI app for a Detroit coffee shop, featuring menu browsing, item customization and interactive customer feedback.
Project Snapshot
- Platform: iOS (SwiftUI)
- Type: Coffee shop ordering & menu browsing
- Focus: Item customization and customer engagement
- Team: 1
- Role: Lead iOS Developer, UI/UX Designer
- Timeline: Oct 2025 - Oct 2025
Unique Value
- Modernizes local coffee shop ordering with a mobile-first app.
- Interactive features like confetti celebration and direct call links enhance customer experience.
- Flexible item customization and modular architecture for easy menu expansion.
- Accessibility-first design ensures usability for all users.
Key Features
- Custom Item Model: Menu items support customization and price calculation.
- Order Number Utility: Unique, timestamped order numbers for tracking.
- Confetti Celebration: Positive feedback after placing orders.
- Direct Call Link: Call the cafe directly from the app.
Technical Breakdown
- MVVM with SwiftUI: Clean separation of UI and logic.
- Custom Item Logic: Flexible menu item customization and price calculation.
- Order Number Utility: Unique order numbers for tracking.
- UIKit Integration: Confetti animation for celebratory feedback.
- Accessibility: Large touch targets, clear color contrast, and direct call functionality.
Code Snippet
Items.swift: Custom item model and price calculation.
struct Item: Identifiable, Hashable {
enum ItemType: String, CaseIterable { case drink, pastry }
let id = UUID()
var name: String
var assetName: String
var prices: Double
var sizes: Sizes = .Small
var milks: Milks = .Whole
var shots: Int = 0
var iced: Bool = false
var toGo: Bool = false
var description: String
var itemType: ItemType
var basePrice: Double
func calculatePrice() -> Double {
var price = basePrice * sizes.basePrice
let taxRate = 0.08
if milks == .Almond { price += 0.5 }
if milks == .Oat { price += 0.5 }
if milks == .Soy { price += 0.5 }
if milks == .Coconut { price += 0.5 }
return price + (1 * taxRate)
}
}
Code Snippet
OrderUtility.swift: Unique order number generation.
struct OrderUtility {
static func generateOrderNumber() -> String {
let now = Date()
let datePart = now.formatted(.verbatim("\(year: .padded(4))\(month: .twoDigits)\(day: .twoDigits)", timeZone: .current, calendar: .current))
let random = Int.random(in: 100...999)
return "ORD-\(datePart)-\(random)"
}
}
Code Snippet
ConfettiTestPage.swift: Confetti celebration after placing an order.
struct ConfettiTestPage: View {
@State private var isCelebrating = false
var body: some View {
ZStack {
ConfettiView(isAnimating: $isCelebrating)
Button(action: {
isCelebrating = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3.5) {
isCelebrating = false
}
}) { Text("Celebrate") }
}
}
}
Code Snippet
CallView.swift: Direct call link for the cafe.
struct CallView: View {
let phoneNumber = "313-277-4736"
var body: some View {
Link("Call \(phoneNumber)", destination: URL(string: "tel:\(phoneNumber.cleaned)")!)
}
}
extension String {
var cleaned: String {
self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
}
}
Project Learnings
- Built modular SwiftUI apps with custom item logic and reusable components.
- Enhanced customer engagement with confetti feedback and direct call links.
- Applied MVVM and best practices for scalable, maintainable code.
Future Iteration
- Add a fully functional cart and checkout system for in-app ordering.
- Integrate payment processing and order history.
- Enable push notifications for order status and cafe updates.
- Expand menu customization and add loyalty rewards.
- Improve accessibility and localization for broader reach.