# Project export: Trip Buddies

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 10.0
- Tagline: With Trip Buddies, affordable adventures are just a click away. Journey a budget-friendly adventure with your closest friends. Relieve your stress and live in the moment! 🌴🌄🌆✈️👝
- Devpost: https://devpost.com/software/travel-buddies-4fsvrj
- GitHub: https://github.com/nnicolee/Travel
- Team: 3 GitHub contributor(s) — CatherWang (13 commits), Nicole Lee (11 commits), angiebaik (4 commits)

## Devpost submission (written by the team)

### Overview

In our search for ideas, one thing became clear: we missed our hometown friends, but our college schedules and tight budgets made planning outings tough. We wanted an something to help us. It's all about budget-friendly adventures and the emotional support of traveling with friends. Because the journey itself is where the magic happens.

### What it does

This app offers you 2 benefit: First, it simplifies trip planning by letting you create trips with essential information such as the destination, number of friends joining, and the budget. Second, it computes the budget distribution among your fellow travelers, eliminating post-trip financial hassles.

### How we built it

We built Trip Buddies on Xcode with swift.

### Challenges we ran into

We found it difficult to implement some of the UI aspects of the app, like the navigation bar. Figuring out how swift works and the errors with github and xcode.

### Accomplishments we're proud of

That we were able to code a functioning app from learning the language under a short time constraint.

### What we learned

We learned lots about swift code and working with the UI interface instead of just the backend work.

### What's next

Trip Buddies will have to expand their functions and ability to help budgeting, like looking for college discounts that are available. We can also expand towards the profile and social media aspect of the app, where we can link with friends so you can collaborate on a single travel plan. These travel plans can be posted so other people can grab inspiration for their future plans. Furthermore we plan to implement AI to suggest other locations to travel to along with a suggested itinerary

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 12 recognized source files, 29 KB.
- Swift (language) — detected in the code

## Codebase structure (from repository index)

### Files (25 of 25)

```
travelpt2.xcodeproj/project.pbxproj
travelpt2.xcodeproj/project.xcworkspace/contents.xcworkspacedata
travelpt2.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
travelpt2.xcodeproj/project.xcworkspace/xcuserdata/angiebaik.xcuserdatad/UserInterfaceState.xcuserstate
travelpt2.xcodeproj/xcuserdata/angiebaik.xcuserdatad/xcschemes/xcschememanagement.plist
travelpt2.xcodeproj/xcuserdata/nicolelee.xcuserdatad/xcschemes/xcschememanagement.plist
travelpt2/Assets.xcassets/AccentColor.colorset/Contents.json
travelpt2/Assets.xcassets/AppIcon.appiconset/Contents.json
travelpt2/Assets.xcassets/Contents.json
travelpt2/bucketList.swift
travelpt2/ContentView.swift
travelpt2/Data.swift
travelpt2/firstPage.swift
travelpt2/IndivPlan.swift
travelpt2/Navigation.swift
travelpt2/newNavBar.swift
travelpt2/Persistence.swift
travelpt2/PlanDetailView.swift
travelpt2/Preview Content/Preview Assets.xcassets/Contents.json
travelpt2/Preview Content/Preview Assets.xcassets/logo.imageset/Contents.json
travelpt2/receipt.swift
travelpt2/secPage.swift
travelpt2/travelpt2.xcdatamodeld/.xccurrentversion
travelpt2/travelpt2.xcdatamodeld/travelpt2.xcdatamodel/contents
travelpt2/travelpt2App.swift
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- fixed location and labeling
- changed color
- fixed navigation
- made changes
- added receipt
- added navigation bar
- added new files
- fixed errors
- IndivPlans
- adjusted indivplan
- fixed nav
- fixed firstPage
- new code
- added navbar
- added nav bar
- edited navigation
- added check list
- added generate random destination
- added location
- added new pages

## Key source files (fetched from GitHub, selected and truncated for size)

### travelpt2/travelpt2App.swift

```swift
//
//  travelpt2App.swift
//  travelpt2
//
//  Created by Nicole Lee on 10/28/23.
//

import SwiftUI

@main
struct travelpt2App: App {
    let persistenceController = PersistenceController.shared

    var body: some Scene {
        WindowGroup {
            Navigation()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

```

### travelpt2/Data.swift

```swift
//
//  Data.swift
//  travelpt2
//
//  Created by Nicole Lee on 10/28/23.
//
import SwiftUI
struct Data: Identifiable {
    let id = UUID()
    let imageName: String
    let name: String
    let location: String
    let friends: String
    let budget: String
}
struct DataList: Identifiable{
    let id = UUID()
    @State public var datas: [Data] = []
    static var datas2: [Data] = []
    
    
    func getDatas() -> [Data] {
        return datas
    }
    
    func addData(imageName: String, name: String, location: String, friends: String, budget: String) {
        let newData = Data(imageName:"uwu", name: name, location: location, friends: friends, budget: budget)
        self.datas.append(newData)
    }
}
//List of directory clubs to make it look realistic LOL
struct dataList {
    static var datas2 = [
        Data(imageName: "placeholder",
             name: "Joe",
             location: "hawaii",
             friends: "3",
             budget: "$400"),
        Data(imageName: "placeholder",
             name: "Joe",
             location: "Paris",
             friends: "3",
             budget: "$400"),
        Data(imageName: "placeholder",
            name: "Joe",
             location: "London",
            friends: "3",
            budget: "$400"),
    ]
}


```

### travelpt2/newNavBar.swift

```swift
//
//  newNavBar.swift
//  travelpt2
//
//  Created by CatherineWang on 10/29/23.
//

import SwiftUI

enum Tab: String, CaseIterable {
    case house
    case calendar
    case plus
    case book
    case clipboard
}

struct newNavbar: View {
    
    @Binding var selectedTab: Tab
    private var fillImage: String {
        selectedTab.rawValue + ""
    }
    
    var body: some View {
        VStack {
            HStack {
                ForEach(Tab.allCases, id: \.rawValue) { tab in
                    Spacer()
                    Image(systemName: selectedTab == tab ? fillImage : tab.rawValue)
                        .scaleEffect(selectedTab == tab ? 1.25 : 1.0)
                        .foregroundColor(selectedTab == tab ? .black : .gray)
                        .font(.system(size: 22))
                        .fontWeight(.semibold)
                        .onTapGesture {
                            withAnimation(.easeIn(duration: 0.1)) {
                                selectedTab = tab
                            }
                        }
                    Spacer()
                }
            }
            .frame(width: nil, height: 60)
            .background(.thinMaterial)
            .cornerRadius(10)
            .padding()
        }
    }
}

struct newNavbar_Previews: PreviewProvider {
    static var previews: some View {
        newNavbar(selectedTab: .constant(.plus))
    }
}

```

### travelpt2/bucketList.swift

```swift
//
//  bucketList.swift
//  travelpt2
//
//  Created by CatherineWang on 10/29/23.
//
import SwiftUI

struct bucketListItem: Identifiable {
    let id = UUID()
    var name: String
    var isCompleted: Bool = false
}

struct bucketList: View {
    @State private var bucketList: [bucketListItem] = []
    @State private var newItemName = ""

    var body: some View {
        VStack {
            Text("My Bucket List")
                .font(.largeTitle)
                .padding()

            List {
                ForEach(bucketList) { item in
                    HStack {
                        Text(item.name)
                        Spacer()
                        if item.isCompleted {
                            Image(systemName: "checkmark.circle.fill")
                        }
                    }
                }
                .onDelete(perform: deleteItem)
            }

            HStack {
                TextField("Add new item", text: $newItemName)
                Button("Add") {
                    if !newItemName.isEmpty {
                        bucketList.append(bucketListItem(name: newItemName))
                        newItemName = ""
                    }
                }
            }
            .padding()

            Spacer()
        }
    }

    func deleteItem(at offsets: IndexSet) {
        bucketList.remove(atOffsets: offsets)
    }
}

struct bucketList_Previews: PreviewProvider {
    static var previews: some View {
        bucketList()
    }
}

```

### travelpt2/Navigation.swift

```swift
//
//  Navigation.swift
//  travelpt2
//
//  Created by CatherineWang on 10/29/23.
//
import SwiftUI

struct Navigation: View {
    //Plus icon
    @State var showNewScreen: Bool = false
    
    //Switching tabs
    @State private var selectedTab: Tab = .house
    
    init() {
        UITableView.appearance().isHidden = true
    }
    
    var body: some View {
        
        ZStack {
            VStack {
                TabView(selection: $selectedTab) {
                    if selectedTab == .house {
                        ContentView()
                    }
                    if selectedTab == .calendar {
                        firstPage()
                    }
                    if selectedTab == .plus {
                        secPage()
                    }
                    if selectedTab == .book {
                        bucketList()
                    }
                    if selectedTab == .clipboard {
                        receipt()
                    }
                }
            }
            
            VStack {
                Spacer()
                newNavbar(selectedTab: $selectedTab)
            }
        }
    }
}


struct NewScreen: View {
    
    @Binding var showNewScreen: Bool
    
    var body: some View {
        ZStack(alignment: .topLeading) {
            Color.white
                .edgesIgnoringSafeArea(.all)
            
            Button(action: {
                showNewScreen.toggle()
            }, label: {
                Image(systemName: "xmark")
                    .foregroundColor(.black)
                    .font(.title)
                    .padding(20)
            })
        }
    }
}

struct Navigation_Previews: PreviewProvider {
    static var previews: some View {
        Navigation()
    }
}

```

### travelpt2/PlanDetailView.swift

```swift
//
//  PlanDetailView.swift
//  travelpt2
//
//  Created by CatherineWang on 10/29/23.
//

import SwiftUI

struct PlanDetailView: View {
    var plan: Data
    var body: some View {
        ScrollView {
            VStack {
                Image(plan.imageName)
                    .resizable()
                    .scaledToFit()
                    .frame(maxHeight: .infinity, alignment: .top)
                    .shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 10)
                
                VStack(alignment: .leading, spacing: 16) {
                    VStack(alignment: .leading, spacing: 8){
                        Text(plan.name)
                            .font(.largeTitle)
                            .fontWeight(.bold)
                        Text("Name")
                            .font(.title3)
                            .foregroundColor(.secondary)
                    }
                    
                    Divider()
                    
                    VStack(alignment: .leading, spacing: 8){
                        
                        Text("Location")
                            .font(.title)
                            .fontWeight(.semibold)
                        Text(plan.location)
                        
                        Spacer()
                        
                        
                        
                        Text("Friends")
                            .font(.title)
                            .fontWeight(.semibold)
                        Text(plan.friends)
                
                    }
                }
                .frame(maxWidth: .infinity,  alignment: .leading)
                .padding()
                
            }
            
        }
        .ignoresSafeArea()
        .background(.ultraThinMaterial)
    }
}

struct PlanDetailView_Previews: PreviewProvider {
    static var previews: some View {
        if DataList.datas2.isEmpty {
            Text("No plans to see")
        } else {
            PlanDetailView(plan: DataList.datas2.first!)
        }
    }
}


```

### travelpt2/receipt.swift

```swift
//
//  receipt.swift
//  travelpt2
//
//  Created by CatherineWang on 10/29/23.
//

import SwiftUI

struct receipt: View {
    @State private var number1 = ""
    @State private var number2 = ""
    @State private var result = 0.0

    var body: some View {
        ZStack {
            Color.white // Background color
                .ignoresSafeArea()

            VStack {
                Text("Receipt")
                    .font(.largeTitle)
                    .padding(.top, 20)
                
                Rectangle()
                    .fill(Color.black)
                    .frame(height: 2)
                    .padding(.top, 10)

                HStack {
                    Spacer()
                    Text("Date: \(getCurrentDate())")
                        .font(.caption)
                }
                .padding(10)
                
                HStack {
                    Text("Item 1:")
                    TextField("Enter the first item", text: $number1)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                }

                HStack {
                    Text("Item 2:")
                    TextField("Enter the second item", text: $number2)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                }

                Rectangle()
                    .fill(Color.black)
                    .frame(height: 2)
                    .padding(.top, 10)

                Button("Calculate") {
                    if let num1 = Double(number1), let num2 = Double(number2) {
                        result = num1 + num2
                    } else {
                        result = 0.0 // Handle invalid input
                    }
                }
                .font(.title)
                .padding()

                Text("Total: $\(result, specifier: "%.2f")")
                    .font(.title)
                    .padding()

                Spacer()
            }
            .padding()
        }
    }

    func getCurrentDate() -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "MM/dd/yyyy HH:mm"
        return formatter.string(from: Date())
    }
}
struct receipt_Previews: PreviewProvider {
    static var previews: some View {
        receipt()
    }
}




```

### travelpt2/Persistence.swift

```swift
//
//  Persistence.swift
//  travelpt2
//
//  Created by Nicole Lee on 10/28/23.
//

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
        }
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "travelpt2")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        container.viewContext.automaticallyMergesChangesFromParent = true
    }
}

```

### travelpt2/ContentView.swift

```swift
//
//  ContentView.swift
//  travelpt2
//
//  Created by Nicole Lee on 10/28/23.
//

import SwiftUI
struct ContentView: View {
    @State private var username = ""
    @State private var password = ""
    @State private var wrongUsername = 0
    @State private var wrongPassword = 0
    @State private var showingLoginScreen = false
    
    var body: some View {
        NavigationStack {
            ZStack{
                Color("Color")
                    .ignoresSafeArea()
                    VStack{
                        
                        Image("logo")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 350.0)
                        //.resizable(resizingMode: .stretch) .aspectRatio(contentMode: .fit).frame(height: 400.0)
                        
                        Spacer()
                            .frame(height: 50.0)
                        TextField("Username", text: $username)
                            .padding()
                            .frame(width:300, height:50)
                            .background(Color.black.opacity(0.05))
                            .cornerRadius(10)
                            .border(.black, width: CGFloat(wrongUsername))
                        SecureField("Password", text: $password)
                            .padding()
                            .frame(width:300, height:50)
                            .background(Color.black.opacity(0.05))
                            .cornerRadius(10)
                            .border(.black, width: CGFloat(wrongUsername))
                        Spacer()
                            .frame(height: 50.0)
            

                        NavigationLink(destination: firstPage()) {
                            Text("Log In!")
                            .foregroundColor(Color.white)}
                                .font(/*@START_MENU_TOKEN@*/.title2/*@END_MENU_TOKEN@*/)
                                .foregroundColor(Color("Color"))
                        
                        .padding()
                        .background(Color(hue: 0.697, saturation: 0.785, brightness: 0.368))
                                    .foregroundColor(.white)
                                    .font(.headline)
                                    .cornerRadius(10)
                        
                       
                    }
                    .navigationBarHidden(true)
                    .padding()
                    
        
      
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


```

### travelpt2/IndivPlan.swift

```swift
//
//  IndivPlan.swift
//  travelpt2
//
//  Created by Angie Baik on 10/29/23.
//

import SwiftUI

struct IndivPlan: View {
    var datas: [Data] = DataList.datas2
    var newdatas: [Data] = DataList.datas2
    
    
    var body: some View {
        ScrollView {
            VStack {
                Image("placeholder")
                    .resizable()
                    .scaledToFit()
                    .frame(maxHeight: .infinity, alignment: .top)
                    .shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 10)
                
                VStack(alignment: .leading, spacing: 16) {
                    VStack(alignment: .leading, spacing: 8){
                        List(datas, id:\.id) { data in
                            Text(data.name)
                                .font(.largeTitle)
                                .fontWeight(.bold)
                            Text(data.location)
                                .font(.title2)
                                .foregroundColor(.secondary)
                            Text(data.friends)
                                .font(.title2)
                                .foregroundColor(.secondary)
                            Text(data.budget)
                                .font(.title2)
                                .foregroundColor(.secondary)
                        }
                    }
                    
                    Divider()
                    
                    VStack(alignment: .leading, spacing: 8){
                        Text("Name")
                            .font(.title)
                            .fontWeight(.semibold)
                        
                        
                        Spacer()
                        
                        
                        Text("Location")
                            .font(.title)
                            .fontWeight(.semibold)
                        
                        Text("TBD")
                        
                        Spacer()
                        
                        NavigationLink(destination: bucketList()) {
                            Text("Bucket List")     .font(.title)
                                .fontWeight(.semibold)
                            
                        }
                    }
                    .frame(maxWidth: .infinity,  alignment: .leading)
                    .padding()
                    
                }
                
            }
            .ignoresSafeArea()
            .background(.ultraThinMaterial)
        }
    }
    
    struct IndivPlan_Previews: PreviewProvider {
        static var previews: some View {
            IndivPlan()
        }
    }
    
    // IndivPlan(plan: dataList.datas2.first())/
}

```

[2 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]