forked from sagnik/Project_Velocity
Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local> Reviewed-on: sagnik/Project_Velocity#29
94 lines
4.4 KiB
Swift
94 lines
4.4 KiB
Swift
import SwiftUI
|
|
|
|
struct EdgeNotesView: View {
|
|
@State private var store = EdgeAppStore.shared
|
|
@State private var noteText = ""
|
|
|
|
var body: some View {
|
|
EdgeShell(
|
|
title: "Notes",
|
|
subtitle: "Capture fast operator memory with a cleaner live-writing surface."
|
|
) {
|
|
if let error = store.errorMessage {
|
|
EdgeErrorCard(message: error)
|
|
}
|
|
|
|
if store.isLoading && store.selectedLead == nil {
|
|
EdgeLoadingCard(message: "Fetching live lead and memory context.")
|
|
} else if let lead = store.selectedLead {
|
|
EdgeHeroCard(
|
|
title: "Quick Capture",
|
|
subtitle: "Write production notes directly against the current highest-priority lead.",
|
|
icon: "square.and.pencil.circle.fill"
|
|
) {
|
|
HStack(spacing: 8) {
|
|
EdgeStatusPill(label: lead.name, color: EdgeTheme.accent)
|
|
EdgeStatusPill(label: lead.unitInterest, color: EdgeTheme.accentWarm)
|
|
}
|
|
}
|
|
|
|
EdgeCard(title: "Lead memory") {
|
|
Text(lead.name)
|
|
.font(.system(size: 19, weight: .bold, design: .rounded))
|
|
.foregroundStyle(EdgeTheme.foreground)
|
|
|
|
if store.memoryFacts.isEmpty {
|
|
Text("No persisted memory facts yet.")
|
|
.font(.system(size: 13, weight: .medium, design: .rounded))
|
|
.foregroundStyle(EdgeTheme.mutedFg)
|
|
} else {
|
|
ForEach(store.memoryFacts) { fact in
|
|
EdgeTimelineRow(
|
|
title: fact.factType.replacingOccurrences(of: "_", with: " ").capitalized,
|
|
subtitle: fact.factText,
|
|
trailing: "Memory",
|
|
tint: EdgeTheme.accentSecondary
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
EdgeCard(title: "Create quick note") {
|
|
TextField("Operator note", text: $noteText, axis: .vertical)
|
|
.textFieldStyle(.plain)
|
|
.textInputAutocapitalization(.sentences)
|
|
.foregroundStyle(EdgeTheme.foreground)
|
|
.padding(14)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 18, style: .continuous)
|
|
.fill(Color.white.opacity(0.05))
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 18, style: .continuous)
|
|
.stroke(EdgeTheme.borderSubtle, lineWidth: 1)
|
|
)
|
|
)
|
|
|
|
Button {
|
|
Task {
|
|
await store.createNote(noteText.trimmingCharacters(in: .whitespacesAndNewlines))
|
|
if store.noteStatusMessage?.localizedCaseInsensitiveContains("saved") == true {
|
|
noteText = ""
|
|
}
|
|
}
|
|
} label: {
|
|
Label("Save note", systemImage: "paperplane.fill")
|
|
}
|
|
.buttonStyle(EdgePrimaryButtonStyle(enabled: !noteText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && EdgeAppConfig.isConfigured))
|
|
.disabled(noteText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || !EdgeAppConfig.isConfigured)
|
|
|
|
if let noteStatusMessage = store.noteStatusMessage {
|
|
Text(noteStatusMessage)
|
|
.font(.system(size: 12, weight: .semibold, design: .rounded))
|
|
.foregroundStyle(noteStatusMessage.localizedCaseInsensitiveContains("saved") ? EdgeTheme.success : EdgeTheme.danger)
|
|
}
|
|
}
|
|
} else {
|
|
EdgeEmptyCard(title: "Notes", message: "No live lead is available yet, so note capture cannot be targeted.")
|
|
}
|
|
}
|
|
.task { await store.refresh(screen: "notes") }
|
|
.refreshable { await store.refresh(screen: "notes") }
|
|
.edgeAutoRefresh(store: store, screen: "notes")
|
|
}
|
|
}
|