Skip to content

Commit e6b973d

Browse files
committed
feat(freeInputPartIOS): adding the freeInputPart of IOS
1 parent 03c769a commit e6b973d

File tree

3 files changed

+70
-12
lines changed

3 files changed

+70
-12
lines changed

xpeapp_ios/XpeApp/XpeApp/Data/DataSource/Mocks/MockWordpressAPI.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class MockWordpressAPI: WordpressAPIProtocol {
2121
var fetchCampaignsProgressReturnData: [QvstProgressModel]?
2222
var fetchUserInfosReturnData: UserInfosModel?
2323
var updatePasswordData: UserPasswordEditReturnEnum?
24+
var submitOpenAnswersReturnData: Bool?
2425

2526
private init() {
2627
// This initializer is intentionally left empty to make private
@@ -72,4 +73,8 @@ class MockWordpressAPI: WordpressAPIProtocol {
7273
func updatePassword(userPasswordCandidate: UserPasswordEditModel) async -> UserPasswordEditReturnEnum? {
7374
return updatePasswordData
7475
}
76+
77+
func submitOpenAnswers(text: String) async -> Bool? {
78+
return submitOpenAnswersReturnData
79+
}
7580
}

xpeapp_ios/XpeApp/XpeApp/Data/DataSource/WordpressAPI.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,25 @@ class WordpressAPI: WordpressAPIProtocol {
308308
}
309309
return nil
310310
}
311+
312+
313+
// send the open answer of a campaign QVST
314+
func submitOpenAnswers(
315+
text: String
316+
) async -> Bool? {
317+
if let (data, _) = await fetchWordpressAPI (
318+
endpoint: "xpeho/v1/qvst/open-answers?text=\(text)",
319+
method: .post,
320+
headers: [:]
321+
){
322+
if let dataString = String(data: data, encoding: .utf8) {
323+
return dataString.contains("true")
324+
} else {
325+
return nil
326+
}
327+
} else {
328+
return nil
329+
}
330+
}
331+
311332
}

xpeapp_ios/XpeApp/XpeApp/Presentation/View/Qvst/CampaignFormView.swift

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct CampaignForm: View {
1818
@State var questions: [QvstQuestionModel] = []
1919
@State var answersSelected: [QvstAnswerModel?] = []
2020
@State var questionsOffset: Int = 0
21+
@State var openAnswer: String = ""
2122

2223
// Prevent multiple click on send button of the form
2324
@State private var isSending: Bool = false
@@ -42,6 +43,8 @@ struct CampaignForm: View {
4243
answersSelected: $answersSelected,
4344
questionsOffset: $questionsOffset
4445
)
46+
} else if isLastOffset() {
47+
OpenAnswerView(openAnswer: $openAnswer)
4548
}
4649
}
4750
}
@@ -55,7 +58,7 @@ struct CampaignForm: View {
5558
}
5659
.disabled(isFirstOffset())
5760
Spacer()
58-
Text("Question \(questionsOffset+1)/\(questions.count)")
61+
Text("Question \(questionsOffset+1)/\(questions.count+1)")
5962
.font(.raleway(.semiBold, size: 20))
6063
.foregroundStyle(XPEHO_THEME.XPEHO_COLOR)
6164
Spacer()
@@ -67,7 +70,7 @@ struct CampaignForm: View {
6770
if isLastOffset() {
6871
sendAnswers()
6972
} else if isAnsweredOffset() {
70-
questionsOffset+=1
73+
questionsOffset += 1
7174
}
7275
}
7376
.disabled(!isAnsweredOffset())
@@ -99,7 +102,7 @@ struct CampaignForm: View {
99102

100103
ChoiceSelector(
101104
choicesAvailable: question.answers.map { $0.answer },
102-
defaultSelectedChoice: answersSelected[questionsOffset]?.answer,
105+
defaultSelectedChoice: answersSelected.indices.contains(questionsOffset) ? answersSelected[questionsOffset]?.answer : nil,
103106
onPress: { choice in
104107
for answerAvailable in question.answers {
105108
if answerAvailable.answer == choice {
@@ -116,21 +119,44 @@ struct CampaignForm: View {
116119
}
117120
}
118121

122+
struct OpenAnswerView: View {
123+
@Binding var openAnswer: String
124+
125+
var body: some View {
126+
VStack(spacing: 20) {
127+
Text("Des remarques ?")
128+
.font(.raleway(.semiBold, size: 16))
129+
.foregroundStyle(XPEHO_THEME.CONTENT_COLOR)
130+
.frame(maxWidth: .infinity, alignment: .leading)
131+
132+
InputText(
133+
label: "Remarques",
134+
onInput: { input in
135+
self.openAnswer = input
136+
}
137+
)
138+
}
139+
.padding(.vertical, 12)
140+
}
141+
}
119142
// Methods to make clear the conditions of appearance
120143
private func isValidOffset() -> Bool {
121144
return (questionsOffset >= 0) && (questionsOffset < questions.count)
122145
}
123146

124147
private func isLastOffset() -> Bool {
125-
return (questionsOffset+1 == questions.count)
148+
return (questionsOffset == questions.count)
126149
}
127150

128151
private func isFirstOffset() -> Bool {
129152
return (questionsOffset == 0)
130153
}
131154

132155
private func isAnsweredOffset() -> Bool {
133-
return (!answersSelected.isEmpty) && (answersSelected[questionsOffset] != nil)
156+
if questionsOffset == questions.count {
157+
return !openAnswer.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
158+
}
159+
return answersSelected.indices.contains(questionsOffset) && answersSelected[questionsOffset] != nil
134160
}
135161

136162
// Init questions of the campaign
@@ -152,18 +178,17 @@ struct CampaignForm: View {
152178
routerManager.goBack()
153179
return
154180
}
155-
156181
self.questions = questions
157182
self.answersSelected = Array(repeating: nil, count: self.questions.count)
158183
}
159184
}
160185

161-
// Send answers of the campaign
162186
private func sendAnswers() {
163187
guard let campaign = routerManager.parameters["campaign"] as! QvstCampaignEntity? else {
164188
debugPrint("No campaign selected")
165189
return
166190
}
191+
167192
Task {
168193
// Get user id for the request
169194
guard let user = LoginManager.instance.getUser() else {
@@ -173,14 +198,14 @@ struct CampaignForm: View {
173198

174199
// Check that all questions has been answered
175200
var answers: [QvstAnswerModel] = []
176-
for index in answersSelected.indices {
201+
for index in 0..<questions.count {
177202
guard let answer = answersSelected[index] else {
178203
debugPrint("Not all questions have been answered")
179204
return
180205
}
181206
answers.append(answer)
182207
}
183-
208+
184209
if !isSending {
185210
// Lock to prevent multi sending by spaming button
186211
isSending = true
@@ -192,11 +217,19 @@ struct CampaignForm: View {
192217
answers: answers
193218
) else {
194219
debugPrint("Failed to send campaign answers")
220+
isSending = false
195221
return
196222
}
197-
223+
224+
guard let isOpenAnswerSent = await WordpressAPI.instance.submitOpenAnswers(text: openAnswer)
225+
else {
226+
debugPrint("Failed to send send open answer")
227+
isSending = false
228+
return
229+
}
230+
198231
// Check the return to inform user
199-
if (!areAnswersSent) {
232+
if (!areAnswersSent && !isOpenAnswerSent) {
200233
// Inform user
201234
toastManager.setParams(
202235
message: "Impossible d'envoyer vos réponses",
@@ -220,4 +253,3 @@ struct CampaignForm: View {
220253
}
221254
}
222255
}
223-

0 commit comments

Comments
 (0)