Skip to content

Commit 85850e7

Browse files
committed
[Fix] 신규, 인기 쿠폰 더보기 쿠폰 다운로드 클릭 시 팝업 표시
1 parent d536e92 commit 85850e7

7 files changed

Lines changed: 235 additions & 154 deletions

File tree

MarketPlace/Model/CouponBasicModel.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct CouponBasicModel: Codable, Identifiable {
1919
var thumbnail: String
2020
var isAvailable: Bool
2121
var isMemberIssued: Bool
22+
var couponType: String
2223

2324
var id: Int { couponId }
2425
}

MarketPlace/Model/CouponModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct CouponNewModel: Codable, Identifiable {
3636
}
3737

3838
struct CouponValidModel: Codable, Identifiable {
39-
let couponId: Int
39+
var couponId: Int
4040
let couponName: String
4141
let couponDescription: String
4242
let deadLine: String?

MarketPlace/View/Components/CouponInfoCell.swift

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@ import SwiftUI
22

33
struct CouponInfoCell: View {
44
@ObservedObject var viewModel: CouponInfoCellViewModel
5+
@EnvironmentObject var loginViewModel: LoginViewModel
56

7+
@Binding var isLoginRequiredPopupVisible: Bool
8+
@Binding var isPopupVisible: Bool
9+
@Binding var coupon: CouponBasicModel
10+
611
var isMemberIssued: Bool { return viewModel.coupon.isMemberIssued }
712

8-
init(viewModel: CouponInfoCellViewModel) {
13+
init(
14+
viewModel: CouponInfoCellViewModel,
15+
isLoginRequiredPopupVisible: Binding<Bool>,
16+
isPopupVisible: Binding<Bool>,
17+
coupon: Binding<CouponBasicModel>
18+
) {
919
self.viewModel = viewModel
20+
self._isLoginRequiredPopupVisible = isLoginRequiredPopupVisible
21+
self._isPopupVisible = isPopupVisible
22+
self._coupon = coupon
1023
}
1124

12-
@State private var showDownloadSuccess = false
13-
1425
var body: some View {
1526
HStack(alignment: .top) {
1627
ShimmeringAsyncImage(
@@ -26,6 +37,7 @@ struct CouponInfoCell: View {
2637
Text(viewModel.coupon.marketName)
2738
.pretendardFont(size: 14, weight: .semibold)
2839
.foregroundColor(Color(hex: "333333"))
40+
.padding(.bottom, 3)
2941

3042
Text(viewModel.coupon.couponName)
3143
.pretendardFont(size: 18, weight: .bold)
@@ -42,16 +54,17 @@ struct CouponInfoCell: View {
4254
Text(viewModel.coupon.address)
4355
.pretendardFont(size: 13, weight: .medium)
4456
.foregroundColor(Color(hex: "333333"))
57+
4558
Spacer()
4659

4760
Button(action: {
48-
if !isMemberIssued {
49-
Task {
50-
let result = await viewModel.downloadCoupon(couponId: viewModel.coupon.couponId)
51-
await MainActor.run {
52-
showDownloadSuccess = result
53-
}
54-
}
61+
if !loginViewModel.isLoggedIn {
62+
isLoginRequiredPopupVisible = true
63+
}
64+
65+
else if !isMemberIssued && loginViewModel.isLoggedIn {
66+
coupon = viewModel.coupon
67+
isPopupVisible = true
5568
}
5669
}, label: {
5770
Image(isMemberIssued ? "download_used" : "download")
@@ -64,18 +77,7 @@ struct CouponInfoCell: View {
6477
}
6578
.padding(.leading, 10)
6679
.padding(5)
67-
.frame(maxHeight: 110)
6880
}
6981
.padding(15)
70-
.alert("쿠폰 다운로드 완료", isPresented: $showDownloadSuccess) {
71-
Button("확인", role: .cancel) { }
72-
} message: {
73-
Text("쿠폰이 성공적으로 발급되었습니다.")
74-
}
75-
.alert(viewModel.errorMessage ?? "오류", isPresented: .constant(viewModel.errorMessage != nil)) {
76-
Button("확인", role: .cancel) {
77-
viewModel.errorMessage = nil
78-
}
79-
}
8082
}
8183
}

MarketPlace/View/Main/View/CouponGetPopupView.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import SwiftUI
22

33
struct CouponGetPopupView: View {
44
@Binding var isPopupVisible: Bool
5-
@Binding var coupon: CouponValidModel
5+
@Binding var couponId: Int
6+
@Binding var couponType: String
7+
@Binding var isMemberIssued: Bool
68

79
@ObservedObject var viewModel = CouponPopupViewModel()
810

@@ -62,22 +64,21 @@ struct CouponGetPopupView: View {
6264
.padding(.vertical, 32)
6365
.background(Color.white)
6466
.cornerRadius(8)
65-
// .shadow(radius: 10)
6667
}
6768
}
6869

6970
private func onConfirm() {
70-
coupon.isMemberIssued = true
71+
isMemberIssued = true
7172
isPopupVisible = false
7273

73-
switch coupon.couponType {
74+
switch couponType {
7475
case "PAYBACK":
7576
Task {
76-
await viewModel.downloadPaybackCoupons(couponId: coupon.couponId)
77+
await viewModel.downloadPaybackCoupons(couponId: couponId)
7778
}
7879
case "GIFT":
7980
Task {
80-
await viewModel.downloadCoupons(couponId: coupon.couponId)
81+
await viewModel.downloadCoupons(couponId: couponId)
8182
}
8283

8384
default:

MarketPlace/View/Main/View/MarketDetailView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ struct MarketDetailView: View {
161161
) {
162162
CouponGetPopupView(
163163
isPopupVisible: $isPopupVisible,
164-
coupon: couponBinding
164+
couponId: couponBinding.couponId,
165+
couponType: couponBinding.couponType,
166+
isMemberIssued: couponBinding.isMemberIssued
165167
).transition(.scale)
166168
}
167169

MarketPlace/View/Main/View/NewEventDetailView.swift

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,108 @@ import SwiftUI
33

44
struct NewEventDetailView: View {
55
@Environment(\.presentationMode) var presentationMode
6+
@EnvironmentObject var loginViewModel: LoginViewModel
7+
68
@ObservedObject var viewModel = NewEventViewModel()
9+
10+
@State private var isLoginRequiredPopupVisible: Bool = false
11+
@State private var isPopupVisible: Bool = false
12+
@State private var showLoginView: Bool = false
13+
@State private var selectedCoupon: CouponBasicModel = CouponBasicModel(couponId: 0, couponName: "", marketId: 0, marketName: "", address: "", thumbnail: "", isAvailable: false, isMemberIssued: false, couponType: "")
14+
715
var currentMonth: String
816

917
var body: some View {
10-
VStack(spacing: 0) {
11-
Divider()
12-
.background(Color.gray.opacity(0.5))
13-
ScrollView {
14-
LazyVStack(spacing: 16) {
15-
ForEach(Array(viewModel.newCoupons.enumerated()), id: \.offset) { index, coupon in
16-
NavigationLink(destination:
17-
MarketDetailView(marketId: coupon.marketId)
18-
) {
19-
let coupon = CouponBasicModel(
20-
couponId: coupon.couponId,
21-
couponName: coupon.couponName,
22-
marketId: coupon.marketId,
23-
marketName: coupon.marketName,
24-
address: coupon.address,
25-
thumbnail: coupon.thumbnail,
26-
isAvailable: coupon.isAvailable,
27-
isMemberIssued: coupon.isMemberIssued
28-
)
29-
30-
VStack {
31-
CouponInfoCell(
32-
viewModel: CouponInfoCellViewModel(coupon: coupon)
18+
ZStack {
19+
VStack(spacing: 0) {
20+
Divider()
21+
.background(Color.gray.opacity(0.5))
22+
ScrollView {
23+
LazyVStack(spacing: 16) {
24+
ForEach(Array(viewModel.newCoupons.enumerated()), id: \.offset) { index, coupon in
25+
NavigationLink(destination:
26+
MarketDetailView(marketId: coupon.marketId)
27+
) {
28+
let coupon = CouponBasicModel(
29+
couponId: coupon.couponId,
30+
couponName: coupon.couponName,
31+
marketId: coupon.marketId,
32+
marketName: coupon.marketName,
33+
address: coupon.address,
34+
thumbnail: coupon.thumbnail,
35+
isAvailable: coupon.isAvailable,
36+
isMemberIssued: coupon.isMemberIssued,
37+
couponType: coupon.couponType
3338
)
39+
40+
VStack {
41+
CouponInfoCell(
42+
viewModel: CouponInfoCellViewModel(coupon: coupon),
43+
isLoginRequiredPopupVisible: $isLoginRequiredPopupVisible,
44+
isPopupVisible: $isPopupVisible,
45+
coupon: $selectedCoupon
46+
)
47+
48+
Divider()
49+
.background(Color.gray.opacity(0.5))
50+
.padding(.horizontal, -20)
51+
}
52+
}.onAppear {
53+
guard index == viewModel.newCoupons.count - 1,
54+
let lastId = viewModel.lastCouponId,
55+
let lastCreated = viewModel.lastCreatedAt,
56+
let lastCouponType = viewModel.lastCouponType
57+
else { return }
3458

35-
Divider()
36-
.background(Color.gray.opacity(0.5))
37-
.padding(.horizontal, -20)
38-
}
39-
}.onAppear {
40-
guard index == viewModel.newCoupons.count - 1,
41-
let lastId = viewModel.lastCouponId,
42-
let lastCreated = viewModel.lastCreatedAt,
43-
let lastCouponType = viewModel.lastCouponType
44-
else { return }
45-
46-
Task {
47-
await viewModel.fetchLatestCoupons(
48-
lastCreatedAt: lastCreated,
49-
lastCouponId: lastId,
50-
couponType: lastCouponType
51-
)
59+
Task {
60+
await viewModel.fetchLatestCoupons(
61+
lastCreatedAt: lastCreated,
62+
lastCouponId: lastId,
63+
couponType: lastCouponType
64+
)
65+
}
5266
}
5367
}
5468
}
5569
}
5670
}
57-
}
58-
.onAppear {
59-
Task {
60-
await viewModel.fetchLatestCoupons()
71+
.onAppear {
72+
Task {
73+
await viewModel.fetchLatestCoupons()
74+
}
6175
}
62-
}
63-
.navigationTitle("\(currentMonth) 신규 | 멤버십 혜택")
64-
.navigationBarTitleDisplayMode(.inline)
65-
.navigationBarBackButtonHidden(true)
66-
.toolbar {
67-
ToolbarItem(placement: .navigationBarLeading) {
68-
Button(action: {
69-
presentationMode.wrappedValue.dismiss()
70-
}) {
71-
Image(systemName: "chevron.backward")
72-
.foregroundColor(.black)
76+
.navigationTitle("\(currentMonth) 신규 | 멤버십 혜택")
77+
.navigationBarTitleDisplayMode(.inline)
78+
.navigationBarBackButtonHidden(true)
79+
.toolbar {
80+
ToolbarItem(placement: .navigationBarLeading) {
81+
Button(action: {
82+
presentationMode.wrappedValue.dismiss()
83+
}) {
84+
Image(systemName: "chevron.backward")
85+
.foregroundColor(.black)
86+
}
7387
}
7488
}
89+
90+
if !loginViewModel.isLoggedIn && isLoginRequiredPopupVisible {
91+
LoginRequriedPopup(
92+
isPopupVisible: $isLoginRequiredPopupVisible,
93+
showLogin: $showLoginView
94+
).transition(.scale)
95+
}
96+
97+
if isPopupVisible {
98+
CouponGetPopupView(
99+
isPopupVisible: $isPopupVisible,
100+
couponId: $selectedCoupon.couponId,
101+
couponType: $selectedCoupon.couponType,
102+
isMemberIssued: $selectedCoupon.isMemberIssued
103+
).transition(.scale)
104+
}
105+
}
106+
.fullScreenCover(isPresented: $showLoginView) {
107+
LoginView()
75108
}
76109
}
77110
}

0 commit comments

Comments
 (0)