mirror of
https://github.com/pointfreeco/swift-composable-architecture.git
synced 2025-12-20 09:11:33 +01:00
* Fixes for TestingSyncUpForm * Typo, heirarchy -> hierarchy * Typo: recursive -> recursively * Typo: comes -> combines * Further fixes for TestingSyncUpForm * Typo: is -> to be * Typo: add -> we added * Typo: 3 -> 2 * Adding a note to avoid confusion * Add more detail to step * Remove stray whitespace causing a diff to incorrectly display * Removed step documentation for unused code * Typo: apart -> a part * Fix App.Path Equatable conformance * App -> AppReducer to avoid conflict with SwiftUI.App * Fix code file link * Typo: reducer -> reducers * Add missing mock * AppReducer -> AppFeature * Standardize tutorial on `@Shared(.syncUps)` * Fix mainactor placement * Fix transcript param not compiling * Add durationPerAttendee to be usable * Add a minimal dismiss override to fit with the docs * Fix commenting out of Tagged discussion * Fix commenting out of TestingSyncUpDetail discussion * Undo a whitespace change * Partial revert of TestingSyncUpForm-02-code-0004.swift * Undo unintentionally committed code * Revert "Add missing mock" This reverts commit9672ecbd20. * Revert "Fixes for TestingSyncUpForm" This reverts commit5bece14c2a. * wip --------- Co-authored-by: Stephen Celis <stephen@stephencelis.com>
99 lines
2.2 KiB
Swift
99 lines
2.2 KiB
Swift
import ComposableArchitecture
|
|
import SwiftUI
|
|
|
|
@Reducer
|
|
struct SyncUpsList {
|
|
// ...
|
|
}
|
|
|
|
struct SyncUpsListView: View {
|
|
@Bindable var store: StoreOf<SyncUpsList>
|
|
|
|
var body: some View {
|
|
List {
|
|
ForEach(store.$syncUps.elements) { $syncUp in
|
|
NavigationLink(
|
|
state: AppFeature.Path.State.detail(SyncUpDetail.State(syncUp: $syncUp))
|
|
) {
|
|
CardView(syncUp: syncUp)
|
|
}
|
|
.listRowBackground(syncUp.theme.mainColor)
|
|
}
|
|
}
|
|
.sheet(item: $store.scope(state: \.addSyncUp, action: \.addSyncUp)) { addSyncUpStore in
|
|
NavigationStack {
|
|
SyncUpFormView(store: addSyncUpStore)
|
|
.navigationTitle("New sync-up")
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Discard") {
|
|
store.send(.discardButtonTapped)
|
|
}
|
|
}
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
Button("Add") {
|
|
store.send(.confirmAddButtonTapped)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.toolbar {
|
|
Button {
|
|
store.send(.addSyncUpButtonTapped)
|
|
} label: {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
.navigationTitle("Daily Sync-ups")
|
|
}
|
|
}
|
|
|
|
struct CardView: View {
|
|
let syncUp: SyncUp
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading) {
|
|
Text(syncUp.title)
|
|
.font(.headline)
|
|
Spacer()
|
|
HStack {
|
|
Label("\(syncUp.attendees.count)", systemImage: "person.3")
|
|
Spacer()
|
|
Label(syncUp.duration.formatted(.units()), systemImage: "clock")
|
|
.labelStyle(.trailingIcon)
|
|
}
|
|
.font(.caption)
|
|
}
|
|
.padding()
|
|
.foregroundColor(syncUp.theme.accentColor)
|
|
}
|
|
}
|
|
|
|
struct TrailingIconLabelStyle: LabelStyle {
|
|
func makeBody(configuration: Configuration) -> some View {
|
|
HStack {
|
|
configuration.title
|
|
configuration.icon
|
|
}
|
|
}
|
|
}
|
|
|
|
extension LabelStyle where Self == TrailingIconLabelStyle {
|
|
static var trailingIcon: Self { Self() }
|
|
}
|
|
|
|
#Preview {
|
|
NavigationStack {
|
|
SyncUpsListView(
|
|
store: Store(
|
|
initialState: SyncUpsList.State(
|
|
syncUps: [.mock]
|
|
)
|
|
) {
|
|
SyncUpsList()
|
|
}
|
|
)
|
|
}
|
|
}
|