From 7d8716b942fb40c35c9bfd0f4410306b5468e93f Mon Sep 17 00:00:00 2001 From: AKY7 Date: Sun, 23 Mar 2025 13:00:25 -0400 Subject: [PATCH 1/2] support all required tags --- app/threadline/TagView.swift | 87 ++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/app/threadline/TagView.swift b/app/threadline/TagView.swift index a9201bc..75534f4 100644 --- a/app/threadline/TagView.swift +++ b/app/threadline/TagView.swift @@ -11,9 +11,23 @@ struct TagView: View { @State private var tags: [String] = [] @State private var newTag: String = "" @State private var selectedCategory: String? = nil + @State private var selectedSubtype: String? = nil + @State private var selectedFit: String? = nil + @State private var selectedOccasion: String? = nil + @State private var selectedPrecip: String? = nil + @State private var isWinter: Bool? = nil let image: UIImage let categories = ["TOP", "BOTTOM", "OUTERWEAR", "DRESS", "SHOES"] + let topSubtypes = ["ACTIVE", "T-SHIRT", "POLO", "BUTTON DOWN", "HOODIE", "SWEATER"] + let bottomSubtypes = ["ACTIVE", "JEANS", "PANTS", "SHORTS", "SKIRT"] + let outerwearSubtypes = ["JACKET", "COAT"] + let dressSubtypes = ["MINI", "MIDI", "MAXI"] + let shoesSubtypes = ["ACTIVE", "SNEAKERS", "BOOTS", "SANDALS & SLIDES"] + let fits = ["LOOSE", "FITTED", "TIGHT"] + let occasions = ["ACTIVE", "CASUAL", "FORMAL"] + let precips = ["RAIN", "SNOW"] + let winterOptions = ["Winter", "Not Winter"] var body: some View { VStack { @@ -23,8 +37,6 @@ struct TagView: View { .frame(height: 200) .padding() - - HStack { TextField("Enter tag", text: $newTag) .textFieldStyle(RoundedBorderTextFieldStyle()) @@ -55,6 +67,53 @@ struct TagView: View { .pickerStyle(MenuPickerStyle()) .padding() + if let selectedCategory = selectedCategory { + Picker("Select Subtype", selection: $selectedSubtype) { + Text("Select Subtype").tag(String?.none) + ForEach(getSubtypes(for: selectedCategory), id: \.self) { subtype in + Text(subtype).tag(String?.some(subtype)) + } + } + .pickerStyle(MenuPickerStyle()) + .padding() + + Picker("Select Fit", selection: $selectedFit) { + Text("Select Fit").tag(String?.none) + ForEach(fits, id: \.self) { fit in + Text(fit).tag(String?.some(fit)) + } + } + .pickerStyle(MenuPickerStyle()) + .padding() + + Picker("Select Occasion", selection: $selectedOccasion) { + Text("Select Occasion").tag(String?.none) + ForEach(occasions, id: \.self) { occasion in + Text(occasion).tag(String?.some(occasion)) + } + } + .pickerStyle(MenuPickerStyle()) + .padding() + + Picker("Select Precipitation", selection: $selectedPrecip) { + Text("Select Precipitation").tag(String?.none) + ForEach(precips, id: \.self) { precip in + Text(precip).tag(String?.some(precip)) + } + } + .pickerStyle(MenuPickerStyle()) + .padding() + + Picker("Winter", selection: $isWinter) { + Text("Select Winter Option").tag(Bool?.none) + ForEach(winterOptions, id: \.self) { option in + Text(option).tag(option == "Winter" ? Bool?.some(true) : Bool?.some(false)) + } + } + .pickerStyle(MenuPickerStyle()) + .padding() + } + ScrollView(.horizontal) { HStack { ForEach(tags, id: \.self) { tag in @@ -85,6 +144,11 @@ struct TagView: View { // Handle done action print("Tags: \(tags)") print("Selected Category: \(selectedCategory ?? "None")") + print("Selected Subtype: \(selectedSubtype ?? "None")") + print("Selected Fit: \(selectedFit ?? "None")") + print("Selected Occasion: \(selectedOccasion ?? "None")") + print("Selected Precipitation: \(selectedPrecip ?? "None")") + print("Winter: \(isWinter == true ? "Yes" : "No")") }) { Text("Done") .padding(.horizontal) @@ -97,10 +161,27 @@ struct TagView: View { .disabled(selectedCategory == nil) } } + + func getSubtypes(for category: String) -> [String] { + switch category { + case "TOP": + return topSubtypes + case "BOTTOM": + return bottomSubtypes + case "OUTERWEAR": + return outerwearSubtypes + case "DRESS": + return dressSubtypes + case "SHOES": + return shoesSubtypes + default: + return [] + } + } } struct TagView_Previews: PreviewProvider { static var previews: some View { TagView(image: UIImage(named: "sampleImage") ?? UIImage()) } -} +} \ No newline at end of file From 40f9aa9b7ad8c6b4e8ce5ba00a49aa74bac38de7 Mon Sep 17 00:00:00 2001 From: AKY7 Date: Sun, 23 Mar 2025 13:29:04 -0400 Subject: [PATCH 2/2] connected to backend - image still required --- app/threadline/TagView.swift | 64 ++++++++++++++++++++++++++++++------ backend/apps/core/views.py | 3 +- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/app/threadline/TagView.swift b/app/threadline/TagView.swift index 75534f4..fd5bc60 100644 --- a/app/threadline/TagView.swift +++ b/app/threadline/TagView.swift @@ -8,6 +8,9 @@ import SwiftUI struct TagView: View { + @AppStorage("username") private var username: String = "" + @Environment(UrlStore.self) private var urlStore + @State private var tags: [String] = [] @State private var newTag: String = "" @State private var selectedCategory: String? = nil @@ -15,7 +18,7 @@ struct TagView: View { @State private var selectedFit: String? = nil @State private var selectedOccasion: String? = nil @State private var selectedPrecip: String? = nil - @State private var isWinter: Bool? = nil + @State private var isWinter: String? = nil let image: UIImage let categories = ["TOP", "BOTTOM", "OUTERWEAR", "DRESS", "SHOES"] @@ -105,9 +108,9 @@ struct TagView: View { .padding() Picker("Winter", selection: $isWinter) { - Text("Select Winter Option").tag(Bool?.none) + Text("Select Winter Option").tag(String?.none) ForEach(winterOptions, id: \.self) { option in - Text(option).tag(option == "Winter" ? Bool?.some(true) : Bool?.some(false)) + Text(option).tag(option == "Winter" ? "True" : "False") } } .pickerStyle(MenuPickerStyle()) @@ -142,13 +145,7 @@ struct TagView: View { Button(action: { // Handle done action - print("Tags: \(tags)") - print("Selected Category: \(selectedCategory ?? "None")") - print("Selected Subtype: \(selectedSubtype ?? "None")") - print("Selected Fit: \(selectedFit ?? "None")") - print("Selected Occasion: \(selectedOccasion ?? "None")") - print("Selected Precipitation: \(selectedPrecip ?? "None")") - print("Winter: \(isWinter == true ? "Yes" : "No")") + sendClothingData() }) { Text("Done") .padding(.horizontal) @@ -178,6 +175,53 @@ struct TagView: View { return [] } } + + func sendClothingData() { + guard let selectedCategory = selectedCategory, + let selectedFit = selectedFit, + let selectedOccasion = selectedOccasion else { + print("Required fields are missing") + return + } + + let payload: [String: Any] = [ + "type": selectedCategory, + "subtype": selectedSubtype ?? "", + "fit": selectedFit, + "occasion": selectedOccasion, + "precip": selectedPrecip ?? "", + "winter": isWinter ?? "False", + "tags": tags, + "username": username + ] + + guard let url = URL(string: "\(urlStore.serverUrl)/clothing/create") else { + print("Invalid URL") + return + } + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + do { + request.httpBody = try JSONSerialization.data(withJSONObject: payload, options: []) + } catch { + print("Error serializing JSON: \(error)") + return + } + + URLSession.shared.dataTask(with: request) { data, response, error in + if let error = error { + print("Error sending clothing data: \(error)") + return + } + if let response = response as? HTTPURLResponse, response.statusCode == 200 { + print("Clothing data sent successfully") + } else { + print("Failed to send clothing data") + } + }.resume() + } } struct TagView_Previews: PreviewProvider { diff --git a/backend/apps/core/views.py b/backend/apps/core/views.py index 15bfba4..1f53ca4 100644 --- a/backend/apps/core/views.py +++ b/backend/apps/core/views.py @@ -17,7 +17,8 @@ @require_method('POST') def create_clothing(request): ## Validate and extract request fields - fields = request.POST + fields = json.loads(request.body.decode('utf-8')) + print(fields) if "username" in fields: username = fields["username"]