From 9ae71323ce9ddd6391f216a8384117c84b413ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cxixn2=E2=80=9D?= Date: Fri, 15 Nov 2024 15:36:45 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20::=20[#63]=20Add=20Expo=20Applicati?= =?UTF-8?q?on=20View=20Publishing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/ExpoApplicationView.swift | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoApplicationView.swift diff --git a/Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoApplicationView.swift b/Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoApplicationView.swift new file mode 100644 index 0000000..7d28200 --- /dev/null +++ b/Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoApplicationView.swift @@ -0,0 +1,249 @@ +// +// ExpoApplicationView.swift +// Expo-iOS +// +// Created by 서지완 on 11/15/24. +// Copyright © 2024 SchoolofCompany. All rights reserved. +// + +import SwiftUI + +struct ExpoApplicationView: View { + @Environment(\.dismiss) var dismiss + @State private var titleTextField: String = "" + @State private var descriptionTextField: String = "" + @State private var locationTextField: String = "" + @State private var locationDetailTextField: String = "" + @State private var date: [String] = ["", ""] + @State private var trainingCount: [String] = [""] + @State private var selectedImage: UIImage? = nil + @State private var isImagePickerPresented = false + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + Text("사진") + .expoFont(.body2B) + .padding(.leading, 14) + .padding(.top, 20) + Button { + isImagePickerPresented.toggle() + } label: { + ZStack { + ExpoIOSAsset.Assets.photoget.swiftUIImage + .resizable() + .frame(maxWidth: .infinity, maxHeight: 185, alignment: .center) + .padding(.top, 8) + .padding(.horizontal, 15) + + selectedImage.map { image in + Image(uiImage: image) + .resizable() + + .frame(height: 173) + .cornerRadius(6) + .padding(.horizontal, 18) + } + .padding(.top, 7.5) + } + } + + HStack(spacing: 6) { + ExpoIOSAsset.Assets.warning.swiftUIImage + + Text("이미지 343 × 178 사이즈로 등록해주세요.") + .expoFont(.caption2R) + .expoColor(ExpoColor.gray300) + } + .padding(.leading, 15) + .padding(.top, 6) + + ExpoTextField( + "제목을 입력해주세요.", + text: $titleTextField, + title: "제목" + ) + .onChange(of: titleTextField) { newValue in + if newValue.count > 30 { + titleTextField = String(newValue.prefix(30)) + } + } + .padding(.top, 28) + + HStack { + Spacer() + Text("\(titleTextField.count)/30") + .padding(.trailing, 16) + .padding(.top, 6) + .expoFont(.caption2R) + .expoColor(ExpoColor.main) + } + + HStack(spacing: -10) { + ExpoTextField( + "시작일", + text: $date[0], + title: "모집기간" + ) + .onChange(of: date[0]) { newValue in + date[0] = formatDateInput(newValue) + } + + ExpoTextField( + "마감일", + text: $date[1] + ) + .padding(.top, 30) + .frame(width: 210) + .onChange(of: date[1]) { newValue in + date[1] = formatDateInput(newValue) + } + } + + HStack(spacing: 6) { + ExpoIOSAsset.Assets.warning.swiftUIImage + + Text("시작일과 마감일 입력시 ‘ yyyy.mm.dd ‘ 형식으로 입력해주세요") + .expoFont(.caption2R) + .expoColor(ExpoColor.gray300) + } + .padding(.leading, 15) + .padding(.top, 6) + + ExpoTextEditor( + "소개글을 작성해주세요.", + text: $descriptionTextField, + title: "소개글" + ) + .onChange(of: descriptionTextField) { newValue in + if newValue.count > 1000 { + descriptionTextField = String(newValue.prefix(1000)) + } + } + .padding(.top, 28) + + HStack { + Spacer() + Text("\(descriptionTextField.count)/1000") + .padding(.trailing, 16) + .padding(.top, 6) + .expoFont(.caption2R) + .expoColor(ExpoColor.main) + } + + Text("연수 종류") + .expoFont(.body2B) + .padding(.leading, 14) + .padding(.top, 28) + .padding(.bottom, 8) + + VStack(spacing: 0) { + ForEach(trainingCount.indices, id: \.self) { index in + HStack(spacing: 0) { + Text("\(index + 1)") + .padding(.leading, 32) + .expoColor(ExpoColor.gray500) + + TextField("연수를 입력해주세요.", text: $trainingCount[index]) + .padding(.leading, 12) + + Spacer() + + Button { + if trainingCount.count > 1 { + trainingCount.remove(at: index) + } + } label: { + ExpoIOSAsset.Assets.grayXButton.swiftUIImage + .padding(.trailing, 32) + } + } + .expoFont(.body2R) + .padding(.bottom, 34) + } + + Button { + trainingCount.append("") + } label: { + HStack(spacing: 8) { + ExpoIOSAsset.Assets.plusBlue.swiftUIImage + Text("추가하기") + .expoFont(.caption1B) + .expoColor(ExpoColor.main300) + } + .padding(.bottom, 26) + } + } + .padding(.top, 26) + .overlay { + RoundedRectangle(cornerRadius: 8) + .strokeBorder(ExpoColor.gray300.swiftUIColor) + .padding(.horizontal, 16) + + } + + Text("장소") + .expoFont(.body2B) + .padding(.leading, 14) + .padding(.top, 28) + .padding(.bottom, 8) + + + ExpoTextField( + "장소를 알려주세요.", + text: $locationTextField + ) + .overlay( + HStack(spacing: 0) { + Spacer() + Button { + /// Action / Daum 위치찾기 + } label: { + ExpoIOSAsset.Assets.location.swiftUIImage + .padding(.trailing, 34) + } + } + ) + + ExpoTextField( + "상세주소를 알려주세요.", + text: $locationDetailTextField + ) + .padding(.top, 8) + + HStack(spacing: 0) { + Spacer() + ExpoButton( + text: "수정 완료", + horizontalPadding: 156, + verticalPadding: 14, + backColor: ExpoColor.main.swiftUIColor, + actionColor: ExpoColor.main300.swiftUIColor + ) + .padding(.top, 24) + .disabled(!isFormValid) + + Spacer() + } + + Spacer() + } + .sheet(isPresented: $isImagePickerPresented) { + ImagePicker(selectedImage: $selectedImage) + } + } + } + + private var isFormValid: Bool { + return !titleTextField.isEmpty && + !descriptionTextField.isEmpty && + !locationTextField.isEmpty && + !locationDetailTextField.isEmpty && + date.allSatisfy { $0.count == 10 } && + selectedImage != nil + } +} + +#Preview { + ExpoApplicationView() +}