Skip to content

Commit 19d98b9

Browse files
tdrhqclaude
andcommitted
Add support chat screen with live timestamp for flakiness demo
Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 68ae81d commit 19d98b9

2 files changed

Lines changed: 106 additions & 1 deletion

File tree

SampleWorkshopApp/LoginView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct LoginView: View {
1515

1616
var body: some View {
1717
if isLoggedIn {
18-
ContentView()
18+
SupportChatView(messages: SupportChatView.sampleMessages)
1919
} else {
2020
loginContent
2121
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// SupportChatView.swift
3+
// SampleWorkshopApp
4+
//
5+
// Created by Arnold Noronha on 2/9/26.
6+
//
7+
8+
import SwiftUI
9+
10+
struct ChatMessage: Identifiable {
11+
let id = UUID()
12+
let text: String
13+
let isFromSupport: Bool
14+
}
15+
16+
struct SupportChatView: View {
17+
@State private var messageText = ""
18+
let messages: [ChatMessage]
19+
20+
var body: some View {
21+
VStack(spacing: 0) {
22+
// Header
23+
HStack {
24+
Circle()
25+
.fill(.green)
26+
.frame(width: 8, height: 8)
27+
Text("Support")
28+
.fontWeight(.semibold)
29+
Spacer()
30+
Text("Online")
31+
.font(.caption)
32+
.foregroundStyle(.secondary)
33+
}
34+
.padding()
35+
.background(Color(.secondarySystemBackground))
36+
37+
// Messages
38+
ScrollView {
39+
LazyVStack(spacing: 12) {
40+
ForEach(messages) { message in
41+
messageBubble(message)
42+
}
43+
}
44+
.padding()
45+
}
46+
47+
// Input bar
48+
HStack(spacing: 12) {
49+
TextField("Type a message...", text: $messageText)
50+
.padding(10)
51+
.background(Color(.secondarySystemBackground))
52+
.cornerRadius(20)
53+
54+
Button {} label: {
55+
Image(systemName: "arrow.up.circle.fill")
56+
.font(.title)
57+
.foregroundStyle(.blue)
58+
}
59+
}
60+
.padding()
61+
}
62+
}
63+
64+
private func messageBubble(_ message: ChatMessage) -> some View {
65+
HStack {
66+
if !message.isFromSupport { Spacer(minLength: 60) }
67+
68+
VStack(alignment: message.isFromSupport ? .leading : .trailing, spacing: 4) {
69+
Text(message.text)
70+
.padding(.horizontal, 12)
71+
.padding(.vertical, 8)
72+
.background(message.isFromSupport ? Color(.secondarySystemBackground) : Color.blue)
73+
.foregroundColor(message.isFromSupport ? .primary : .white)
74+
.cornerRadius(16)
75+
76+
Text(currentTimestamp)
77+
.font(.caption2)
78+
.foregroundStyle(.secondary)
79+
}
80+
81+
if message.isFromSupport { Spacer(minLength: 60) }
82+
}
83+
}
84+
85+
private var currentTimestamp: String {
86+
let formatter = DateFormatter()
87+
formatter.dateFormat = "h:mm a"
88+
return formatter.string(from: Date())
89+
}
90+
}
91+
92+
extension SupportChatView {
93+
static let sampleMessages: [ChatMessage] = [
94+
ChatMessage(text: "Hi! I'm having trouble resetting my password.", isFromSupport: false),
95+
ChatMessage(text: "Hello! I'd be happy to help you with that. Can you tell me the email address associated with your account?", isFromSupport: true),
96+
ChatMessage(text: "Sure, it's [email protected]", isFromSupport: false),
97+
ChatMessage(text: "Thanks! I've sent a password reset link to that email. It should arrive within a few minutes.", isFromSupport: true),
98+
ChatMessage(text: "Got it, thank you so much!", isFromSupport: false),
99+
ChatMessage(text: "You're welcome! Let me know if you need anything else. 😊", isFromSupport: true),
100+
]
101+
}
102+
103+
#Preview {
104+
SupportChatView(messages: SupportChatView.sampleMessages)
105+
}

0 commit comments

Comments
 (0)