Skip to content

Commit

Permalink
Merge pull request #1014 from 0x1-company/invitation-code
Browse files Browse the repository at this point in the history
  • Loading branch information
tomokisun authored Nov 22, 2023
2 parents 0eaf79a + a31394b commit 5ac5646
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 3 deletions.
123 changes: 123 additions & 0 deletions Packages/GodPackage/Sources/OnboardFeature/InvitationCode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import AnalyticsClient
import ComposableArchitecture
import SwiftUI

@Reducer
public struct InvitationCodeLogic {
public init() {}

public struct State: Equatable {
@BindingState var invitationCode = ""
var isDisabled = true
public init() {}
}

public enum Action: BindableAction {
case onTask
case onAppear
case nextButtonTapped
case skipButtonTapped
case binding(BindingAction<State>)
case delegate(Delegate)

public enum Delegate: Equatable {
case nextScreen(String?)
}
}

@Dependency(\.analytics) var analytics

public var body: some Reducer<State, Action> {
BindingReducer()
Reduce<State, Action> { state, action in
switch action {
case .onTask:
return .none

case .onAppear:
analytics.logScreen(screenName: "InvitationCode", of: self)
return .none

case .nextButtonTapped:
let code = state.invitationCode
return .send(.delegate(.nextScreen(code)))

case .skipButtonTapped:
return .send(.delegate(.nextScreen(nil)))

case .binding(\.$invitationCode):
state.isDisabled = state.invitationCode.count != 6
return .none

default:
return .none
}
}
}
}

public struct InvitationCodeView: View {
@FocusState var focus: Bool
let store: StoreOf<InvitationCodeLogic>

public init(store: StoreOf<InvitationCodeLogic>) {
self.store = store
}

public var body: some View {
WithViewStore(store, observe: { $0 }) { viewStore in
VStack(spacing: 12) {
Spacer()
Text("Do you have invitation code?", bundle: .module)
.font(.system(.title3, design: .rounded, weight: .bold))

Text("If you do not have it, you can skip it.", bundle: .module)
.font(.system(.body, design: .rounded))

TextField(text: viewStore.$invitationCode) {
Text("ABCDEF", bundle: .module)
}
.foregroundStyle(.white)
.multilineTextAlignment(.center)
.font(.system(.title, design: .rounded))
.focused($focus)

Spacer()

NextButton(isDisabled: viewStore.isDisabled) {
store.send(.nextButtonTapped)
}

Button {
store.send(.skipButtonTapped)
} label: {
Text("Skip", bundle: .module)
.frame(height: 44)
.frame(maxWidth: .infinity)
.font(.system(.body, design: .rounded))
}
}
.padding(.horizontal, 24)
.padding(.bottom, 16)
.foregroundStyle(Color.white)
.background(Color.godService)
.task { await store.send(.onTask).finish() }
.onAppear {
focus = true
store.send(.onAppear)
}
}
}
}

#Preview {
NavigationStack {
InvitationCodeView(
store: .init(
initialState: InvitationCodeLogic.State(),
reducer: { InvitationCodeLogic() }
)
)
}
.environment(\.locale, Locale(identifier: "ja-JP"))
}
23 changes: 23 additions & 0 deletions Packages/GodPackage/Sources/OnboardFeature/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
}
}
}
},
"ABCDEF" : {

},
"Add a photo so your friends can find you" : {
"localizations" : {
Expand Down Expand Up @@ -147,6 +150,16 @@
}
}
},
"Do you have invitation code?" : {
"localizations" : {
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "招待コードを持っていますか?"
}
}
}
},
"Enable Contacts" : {

},
Expand Down Expand Up @@ -329,6 +342,16 @@
}
}
},
"If you do not have it, you can skip it." : {
"localizations" : {
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "持っていない場合はスキップ出来ます。"
}
}
}
},
"Imported from Contacts" : {
"localizations" : {
"ja" : {
Expand Down
10 changes: 10 additions & 0 deletions Packages/GodPackage/Sources/OnboardFeature/Onboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public struct OnboardLogic {
var schoolId: String?
var clubActivityId: String?
var inviterUserId: String?
var invitationCode: String?
var contacts: [God.ContactInput] = []

public init() {}
Expand Down Expand Up @@ -120,6 +121,7 @@ public struct OnboardLogic {
case schoolSetting(SchoolSettingLogic.State = .init())
case clubActivitySetting(ClubActivitySettingLogic.State = .init())
case findFriend(FindFriendLogic.State = .init())
case invitationCode(InvitationCodeLogic.State = .init())
case phoneNumber(PhoneNumberLogic.State = .init())
case oneTimeCode(OneTimeCodeLogic.State)
case firstNameSetting(FirstNameSettingLogic.State = .init())
Expand All @@ -137,6 +139,7 @@ public struct OnboardLogic {
case schoolSetting(SchoolSettingLogic.Action)
case clubActivitySetting(ClubActivitySettingLogic.Action)
case findFriend(FindFriendLogic.Action)
case invitationCode(InvitationCodeLogic.Action)
case phoneNumber(PhoneNumberLogic.Action)
case oneTimeCode(OneTimeCodeLogic.Action)
case firstNameSetting(FirstNameSettingLogic.Action)
Expand All @@ -154,6 +157,7 @@ public struct OnboardLogic {
Scope(state: \.schoolSetting, action: \.schoolSetting, child: SchoolSettingLogic.init)
Scope(state: \.clubActivitySetting, action: \.clubActivitySetting, child: ClubActivitySettingLogic.init)
Scope(state: \.findFriend, action: \.findFriend, child: FindFriendLogic.init)
Scope(state: \.invitationCode, action: \.invitationCode, child: InvitationCodeLogic.init)
Scope(state: \.phoneNumber, action: \.phoneNumber, child: PhoneNumberLogic.init)
Scope(state: \.oneTimeCode, action: \.oneTimeCode, child: OneTimeCodeLogic.init)
Scope(state: \.firstNameSetting, action: \.firstNameSetting, child: FirstNameSettingLogic.init)
Expand Down Expand Up @@ -204,6 +208,12 @@ public struct OnboardView: View {
action: OnboardLogic.Path.Action.findFriend,
then: FindFriendView.init(store:)
)
case .invitationCode:
CaseLet(
/OnboardLogic.Path.State.invitationCode,
action: OnboardLogic.Path.Action.invitationCode,
then: InvitationCodeView.init(store:)
)
case .phoneNumber:
CaseLet(
/OnboardLogic.Path.State.phoneNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public struct OnboardPathLogic {
return .none

} else if isFindFriendSkip {
state.path.append(.phoneNumber())
state.path.append(.invitationCode())
return .run(priority: .background) { send in
await contactsRequest(send: send)
}
Expand All @@ -75,7 +75,7 @@ public struct OnboardPathLogic {
state.clubActivityId = clubActivityId

if isFindFriendSkip {
state.path.append(.phoneNumber())
state.path.append(.invitationCode())
return .run(priority: .background) { send in
await contactsRequest(send: send)
}
Expand All @@ -84,10 +84,15 @@ public struct OnboardPathLogic {
return .none

case .findFriend(.delegate(.nextScreen)):
state.path.append(.phoneNumber())
state.path.append(.invitationCode())
return .run(priority: .background) { send in
await contactsRequest(send: send)
}

case let .invitationCode(.delegate(.nextScreen(code))):
state.invitationCode = code
state.path.append(.phoneNumber())
return .none

case .phoneNumber(.delegate(.nextScreen)):
state.path.append(
Expand Down

0 comments on commit 5ac5646

Please sign in to comment.