쿠폰 및 공지 화면 다국어 적용

This commit is contained in:
Yu Sung
2025-12-19 19:20:28 +09:00
parent ee4b7c9a79
commit a406935e4f
6 changed files with 222 additions and 68 deletions

View File

@@ -16,7 +16,7 @@ struct UserProfileDonationAllView: View {
var body: some View {
BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) {
DetailNavigationBar(title: "후원랭킹 전체보기")
DetailNavigationBar(title: String(localized: "후원랭킹 전체보기"))
if userId == UserDefaults.int(forKey: .userId) {
VStack(spacing: 10.7) {

View File

@@ -111,6 +111,116 @@ enum I18n {
static var points: String { pick(ko: "포인트", en: "Points", ja: "ポイント") }
}
// /
enum CanCoupon {
//
static var title: String {
pick(ko: "쿠폰등록", en: "Register coupon", ja: "クーポン登録")
}
//
static var inputTitle: String {
pick(ko: "쿠폰번호 입력", en: "Enter coupon code", ja: "クーポン番号入力")
}
static var inputPlaceholder: String {
pick(
ko: "쿠폰번호를 입력하세요",
en: "Enter coupon code",
ja: "クーポン番号を入力してください"
)
}
//
static var submit: String {
pick(ko: "등록하기", en: "Register", ja: "登録する")
}
//
static var guideHeader: String {
pick(ko: "[등록 및 사용안내]", en: "[Registration and usage]", ja: "[登録および利用案内]")
}
static var cautionHeader: String {
pick(ko: "[주의사항]", en: "[Notes]", ja: "[注意事項]")
}
//
static var guide1: String {
pick(
ko: "공백없이 쿠폰번호 12자리를 입력해주세요.",
en: "Enter 12 characters without spaces.",
ja: "スペースなしで12桁のクーポン番号を入力してください。"
)
}
static var guide2: String {
pick(
ko: "충전된 캔 또는 포인트는 해당 충전현황에서 확인할 수 있습니다",
en: "You can check charged cans or points in the charge status.",
ja: "チャージされた缶またはポイントはチャージ状況で確認できます。"
)
}
static var guide3: String {
pick(
ko: "쿠폰으로 충전된 캔은 사용 전까지 소멸되지 않으며, 포인트는 충전 후 72시간 이내에 사용하지 않으면 자동 소멸됩니다.",
en: "Cans charged by coupon do not expire before use. Points expire automatically if not used within 72 hours after charging.",
ja: "クーポンでチャージした缶は使用前に失効しません。ポイントはチャージ後72時間以内に使用しないと自動的に失効します。"
)
}
//
static var caution1: String {
pick(
ko: "이벤트 쿠폰을 통해 충전한 캔이나 포인트는 환불되지 않습니다.",
en: "Cans or points charged via event coupons are non-refundable.",
ja: "イベントクーポンでチャージした缶やポイントは返金できません。"
)
}
static var caution2: String {
pick(
ko: "쿠폰은 상업적 용도로 사용하거나 매매할 수 없습니다.",
en: "Coupons may not be used for commercial purposes or traded.",
ja: "クーポンを商用目的で使用したり売買したりすることはできません。"
)
}
static var caution3: String {
pick(
ko: "한번 등록한 쿠폰은 재사용이 불가합니다.",
en: "A coupon cant be used again once registered.",
ja: "一度登録したクーポンは再使用できません。"
)
}
static var caution4: String {
pick(
ko: "연령 제한 정책에 따라 쿠폰이용은 본인인증한 회원만 이용 가능합니다.",
en: "Due to age policy, only verified members can use coupons.",
ja: "年齢制限ポリシーにより、本人確認済みの会員のみクーポンを利用できます。"
)
}
static var contactHelp: String {
pick(
ko: "※ 쿠폰 등록 및 이용에 문제가 발생한 경우 '고객센터'로 문의주시기 바랍니다.",
en: "※ If you have issues with coupon registration or use, please contact Customer Service.",
ja: "※ クーポンの登録・利用に問題が発生した場合は『カスタマーセンター』までお問い合わせください。"
)
}
// /
static var useCompleted: String {
pick(
ko: "쿠폰 사용이 완료되었습니다.",
en: "Coupon use completed.",
ja: "クーポンの使用が完了しました。"
)
}
}
enum MissionMenu {
static var menu1: String { pick(ko: "메뉴 1", en: "Menu 1", ja: "メニュー1") }
static var menu2: String { pick(ko: "메뉴 2", en: "Menu 2", ja: "メニュー2") }

View File

@@ -17,16 +17,16 @@ struct CanCouponView: View {
BaseView(isLoading: $viewModel.isLoading) {
GeometryReader { proxy in
VStack(spacing: 0) {
DetailNavigationBar(title: "쿠폰등록")
DetailNavigationBar(title: I18n.CanCoupon.title)
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
Text("쿠폰번호 입력")
Text(I18n.CanCoupon.inputTitle)
.font(.custom(Font.bold.rawValue, size: 16.7))
.foregroundColor(Color(hex: "eeeeee"))
.frame(maxWidth: .infinity, alignment: .leading)
TextField("쿠폰번호를 입력하세요", text: $viewModel.couponNumber)
TextField(I18n.CanCoupon.inputPlaceholder, text: $viewModel.couponNumber)
.autocapitalization(.allCharacters) // Force uppercase keyboard
.textContentType(.none)
.disableAutocorrection(true)
@@ -45,7 +45,7 @@ struct CanCouponView: View {
}
}
Text("등록하기")
Text(I18n.CanCoupon.submit)
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(.white)
.padding(.vertical, 16)
@@ -58,17 +58,17 @@ struct CanCouponView: View {
}
VStack(alignment: .leading, spacing: 0) {
Text("[등록 및 사용안내]")
Text(I18n.CanCoupon.guideHeader)
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(.grayee)
CanCouponNoticeItemView(notice: "공백없이 쿠폰번호 12자리를 입력해주세요.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.guide1)
.padding(.top, 8)
CanCouponNoticeItemView(notice: "충전된 캔 또는 포인트는 해당 충전현황에서 확인할 수 있습니다")
CanCouponNoticeItemView(notice: I18n.CanCoupon.guide2)
.padding(.top, 4)
CanCouponNoticeItemView(notice: "쿠폰으로 충전된 캔은 사용 전까지 소멸되지 않으며, 포인트는 충전 후 72시간 이내에 사용하지 않으면 자동 소멸됩니다.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.guide3)
.padding(.top, 4)
Rectangle()
@@ -77,23 +77,23 @@ struct CanCouponView: View {
.background(Color.gray55)
.padding(.vertical, 26.7)
Text("[주의사항]")
Text(I18n.CanCoupon.cautionHeader)
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(.grayee)
CanCouponNoticeItemView(notice: "이벤트 쿠폰을 통해 충전한 캔이나 포인트는 환불되지 않습니다.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.caution1)
.padding(.top, 8)
CanCouponNoticeItemView(notice: "쿠폰은 상업적 용도로 사용하거나 매매할 수 없습니다.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.caution2)
.padding(.top, 4)
CanCouponNoticeItemView(notice: "한번 등록한 쿠폰은 재사용이 불가합니다.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.caution3)
.padding(.top, 4)
CanCouponNoticeItemView(notice: "연령 제한 정책에 따라 쿠폰이용은 본인인증한 회원만 이용 가능합니다.")
CanCouponNoticeItemView(notice: I18n.CanCoupon.caution4)
.padding(.top, 4)
Text("※ 쿠폰 등록 및 이용에 문제가 발생한 경우 '고객센터'로 문의주시기 바랍니다.")
Text(I18n.CanCoupon.contactHelp)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(.grayee)
.fixedSize(horizontal: false, vertical: true)

View File

@@ -42,7 +42,7 @@ final class CanCouponViewModel: ObservableObject {
if let message = decoded.message {
self.errorMessage = message
} else {
self.errorMessage = "쿠폰 사용이 완료되었습니다."
self.errorMessage = I18n.CanCoupon.useCompleted
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
@@ -53,13 +53,13 @@ final class CanCouponViewModel: ObservableObject {
if let message = decoded.message {
self.errorMessage = message
} else {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.errorMessage = I18n.Common.commonError
}
}
self.isShowPopup = true
} catch {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.errorMessage = I18n.Common.commonError
self.isShowPopup = true
}
}

View File

@@ -15,7 +15,7 @@ struct NoticeDetailView: View {
var body: some View {
BaseView {
VStack(spacing: 0) {
DetailNavigationBar(title: "공지사항 상세")
DetailNavigationBar(title: String(localized: "공지사항 상세"))
VStack(alignment: .leading, spacing: 6.7) {
Text(notice.title)