-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from Student-Center/working/WEAV-142
[WEAV-142] 프로필 변경 - 활동 지역 수정
- Loading branch information
Showing
6 changed files
with
571 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
...Features/Home/Sources/Profile/EditProfile/EditProfileRegion/EditProfileRegionIntent.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// | ||
// EditProfileRegionIntent.swift | ||
// Home | ||
// | ||
// Created by 김지수 on 11/25/24. | ||
// Copyright © 2024 com.weave. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import CommonKit | ||
import CoreKit | ||
import NetworkKit | ||
import Model | ||
import DesignCore | ||
|
||
//MARK: - Intent | ||
class EditProfileRegionIntent { | ||
private weak var model: EditProfileRegionModelActionable? | ||
private let input: DataModel | ||
private let regionService: RegionServiceProtocol | ||
private let profileService: ProfileServiceProtocol | ||
let maxSelectCount = 10 | ||
|
||
// MARK: Life cycle | ||
init( | ||
model: EditProfileRegionModelActionable, | ||
input: DataModel, | ||
regionService: RegionServiceProtocol = RegionService.shared, | ||
profileService: ProfileServiceProtocol = ProfileService.shared | ||
) { | ||
self.input = input | ||
self.model = model | ||
self.regionService = regionService | ||
self.profileService = profileService | ||
model.setUserInfo(input.userInfo) | ||
|
||
let selectedRegion = input.userInfo.profile.locations.map { | ||
RegionDomain( | ||
id: $0.id, | ||
mainRegion: "", | ||
subRegion: $0.name | ||
) | ||
} | ||
model.setSelectedSubRegion(selectedRegion) | ||
} | ||
} | ||
|
||
//MARK: - Intentable | ||
extension EditProfileRegionIntent { | ||
protocol Intentable { | ||
// content | ||
func onTapNextButton(state: EditProfileRegionModel.Stateful) | ||
func onTapMainRegion(_ region: String) | ||
func onTapSubRegion( | ||
totalSubRegions: [RegionDomain], | ||
selectedSubRegion: RegionDomain | ||
) | ||
|
||
// default | ||
func onAppear() | ||
func task() async | ||
} | ||
|
||
struct DataModel { | ||
let userInfo: UserInfo | ||
} | ||
} | ||
|
||
//MARK: - Intentable | ||
extension EditProfileRegionIntent: EditProfileRegionIntent.Intentable { | ||
// default | ||
func onAppear() {} | ||
|
||
func task() async { | ||
model?.setLoading(status: true) | ||
let mainRegions = await requestMainRegions() | ||
fetchMainRegions(mainRegions) | ||
guard mainRegions.isNotEmpty else { return } | ||
onTapMainRegion(mainRegions[0]) | ||
let subRegions = await requestSubRegions(mainRegion: mainRegions[0]) | ||
fetchSubRegions(subRegions) | ||
model?.setLoading(status: false) | ||
} | ||
|
||
func onTapMainRegion(_ region: String) { | ||
model?.setSelectedMainRegion(region) | ||
model?.setSubRegions([]) | ||
Task { | ||
let subRegions = await requestSubRegions(mainRegion: region) | ||
fetchSubRegions(subRegions) | ||
} | ||
} | ||
|
||
func onTapSubRegion( | ||
totalSubRegions: [RegionDomain], | ||
selectedSubRegion: RegionDomain | ||
) { | ||
var result = totalSubRegions | ||
|
||
if let index = totalSubRegions | ||
.firstIndex(where: { $0.id == selectedSubRegion.id }) { | ||
result.remove(at: index) | ||
} else { | ||
// 갯수 10개 제한 | ||
guard result.count < maxSelectCount else { return } | ||
result.append(selectedSubRegion) | ||
} | ||
model?.setSelectedSubRegion(result) | ||
} | ||
|
||
func requestMainRegions() async -> [String] { | ||
do { | ||
return try await regionService.requestMainRegions() | ||
} catch { | ||
print(error) | ||
return [] | ||
} | ||
} | ||
|
||
func fetchMainRegions(_ mainRegions: [String]) { | ||
model?.setMainRegions(mainRegions) | ||
} | ||
|
||
func requestSubRegions(mainRegion: String) async -> [RegionDomain] { | ||
do { | ||
return try await regionService.requestSubRegions(mainRegion: mainRegion) | ||
.map { RegionDomain(dto: $0) } | ||
|
||
} catch { | ||
print(error) | ||
return [] | ||
} | ||
} | ||
|
||
func fetchSubRegions(_ subRegions: [RegionDomain]) { | ||
model?.setSubRegions(subRegions) | ||
} | ||
|
||
// content | ||
func onTapNextButton(state: EditProfileRegionModel.Stateful) { | ||
Task { | ||
do { | ||
guard let userInfo = state.userInfo else { return } | ||
model?.setLoading(status: true) | ||
var newUserInfo = userInfo | ||
let newRegions = state.selectedSubRegions.map { LocationModel(id: $0.id, name: $0.subRegion) } | ||
newUserInfo.profile.locations = newRegions | ||
try await requestUpdateProfile(newUserInfo: newUserInfo) | ||
model?.setLoading(status: false) | ||
await MainActor.run { | ||
AppCoordinator.shared.pop() | ||
} | ||
} catch { | ||
print(error) | ||
ToastHelper.showErrorMessage(error.localizedDescription) | ||
model?.setLoading(status: false) | ||
} | ||
} | ||
} | ||
|
||
func requestUpdateProfile(newUserInfo: UserInfo) async throws { | ||
try await profileService.requestPutUserInfo(userInfo: newUserInfo) | ||
} | ||
} |
111 changes: 111 additions & 0 deletions
111
.../Features/Home/Sources/Profile/EditProfile/EditProfileRegion/EditProfileRegionModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// | ||
// EditProfileRegionModel.swift | ||
// Home | ||
// | ||
// Created by 김지수 on 11/25/24. | ||
// Copyright © 2024 com.weave. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import CommonKit | ||
import CoreKit | ||
import Model | ||
|
||
final class EditProfileRegionModel: ObservableObject { | ||
|
||
//MARK: Stateful | ||
protocol Stateful { | ||
// content | ||
var userInfo: UserInfo? { get } | ||
var mainRegions: [String] { get } | ||
var selectedMainRegion: String? { get } | ||
var subRegions: [RegionDomain] { get } | ||
var selectedSubRegions: [RegionDomain] { get } | ||
|
||
var isValidated: Bool { get } | ||
|
||
// default | ||
var isLoading: Bool { get } | ||
|
||
// error | ||
var showErrorView: ErrorModel? { get } | ||
var showErrorAlert: ErrorModel? { get } | ||
} | ||
|
||
//MARK: State Properties | ||
// content | ||
@Published var userInfo: UserInfo? | ||
@Published var mainRegions: [String] = [] | ||
@Published var selectedMainRegion: String? | ||
|
||
@Published var subRegions: [RegionDomain] = [] | ||
@Published var selectedSubRegions: [RegionDomain] = [] | ||
|
||
var isValidated: Bool { | ||
let initialState = userInfo?.profile.locations.map { $0.id } == selectedSubRegions.map { $0.id } | ||
return selectedMainRegion != nil && selectedSubRegions.isNotEmpty && !initialState | ||
} | ||
|
||
// default | ||
@Published var isLoading: Bool = false | ||
|
||
// error | ||
@Published var showErrorView: ErrorModel? | ||
@Published var showErrorAlert: ErrorModel? | ||
} | ||
|
||
extension EditProfileRegionModel: EditProfileRegionModel.Stateful {} | ||
|
||
//MARK: - Actionable | ||
protocol EditProfileRegionModelActionable: AnyObject { | ||
// content | ||
func setUserInfo(_ userInfo: UserInfo) | ||
func setMainRegions(_ regions: [String]) | ||
func setSelectedMainRegion(_ region: String) | ||
func setSubRegions(_ subRegions: [RegionDomain]) | ||
func setSelectedSubRegion(_ subRegions: [RegionDomain]) | ||
|
||
// default | ||
func setLoading(status: Bool) | ||
|
||
// error | ||
func showErrorView(error: ErrorModel) | ||
func showErrorAlert(error: ErrorModel) | ||
func resetError() | ||
} | ||
|
||
extension EditProfileRegionModel: EditProfileRegionModelActionable { | ||
// content | ||
func setUserInfo(_ userInfo: UserInfo) { | ||
self.userInfo = userInfo | ||
} | ||
func setMainRegions(_ regions: [String]) { | ||
mainRegions = regions | ||
} | ||
func setSelectedMainRegion(_ region: String) { | ||
selectedMainRegion = region | ||
} | ||
func setSubRegions(_ subRegions: [RegionDomain]) { | ||
self.subRegions = subRegions | ||
} | ||
func setSelectedSubRegion(_ subRegions: [RegionDomain]) { | ||
self.selectedSubRegions = subRegions | ||
} | ||
|
||
// default | ||
func setLoading(status: Bool) { | ||
isLoading = status | ||
} | ||
|
||
// error | ||
func showErrorView(error: ErrorModel) { | ||
showErrorView = error | ||
} | ||
func showErrorAlert(error: ErrorModel) { | ||
showErrorAlert = error | ||
} | ||
func resetError() { | ||
showErrorView = nil | ||
showErrorAlert = nil | ||
} | ||
} |
Oops, something went wrong.