# Project export: BananaBunks

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: CruzHacks 2025
- Tagline: With Banana Bunks, UCSC students can find roommates/housemates based on their personality and preferences. Swipe on user's profiles to find a match and get connecting. Happy Swiping!
- Devpost: https://devpost.com/software/bananabunks
- GitHub: https://github.com/Techgirl2/BananaBunks
- Team: 2 GitHub contributor(s) — Angelina Cruz (18 commits), Sakshi Konnur (12 commits)

## Devpost submission (written by the team)

### Inspiration

Our inspiration started with us both seeking new living accommodations or looking for a new housemate to move in for next year.

### What it does

Our mobile app takes in user admitted data during the profile set up stage to showcase who you are as a person and as a potential roommate/housemate. Others can then view your engaging profile with our swiping feature to which you can express interest and reach out. If both users swipe right, there is a match! This match will show up on our feed with their contact information.

### How we built it

We built our app using React Native, Expo, and TypeScript.

### Challenges we ran into

Setting up our app was a huge challenge as we never used these frameworks before. We would often run into configuration issues, caching stalls, and Expo CLI / Metro bundler errors.

### Accomplishments we're proud of

We are proud of not giving up on our initial idea even though setting up the app took way longer than anticipated. It was an ambitious project and it wasn't easy to work on it with just two people, which made our progress all the more rewarding.

### What we learned

We learned new frameworks and how to integrate our ideas into a mobile app!

### What's next

We would love to implement a messaging feature next. Stay tuned.

## README (from the GitHub repository)

# BananaBunks

npm run start 
to automatically run all the right commands

MVP: 
- let a user make an account and login [DONE]

- outline edit profile workflow on the frontend
- store user data like living prefrerences, hobbies, etc. in JSON in firestore [DONE]

- implement UI from figma for edit profile pages, main profile page, swiping page, matched page [DONE]

- once you have a lot of user data created, implement simple swiping functionality where you're just listing all other users on the platform in arbitrary or sequential order [DONE]

- if a match is mutual, have the corresponding person's profile show up on the "matched" section of the app [DONE]

- once all this is done, see if you can implement some kind of matching algorithm 

- continue tweaking UI/UX 

- project inspiration : has utility to both of our lives, angelina trying to fill single, I'm trying to find housing for the next year
- our struggles  : expo compatibility, nativewind/babel stuff use screenshots if you have any 
- this isn't supposed to handle every single aspect of shared living, we give some responsibility to the user to reach out to the people they've matched with using their email handles to discuss the more specific things 
- this is also why we've provided the personal description field so users have the flexibility to truly show what they're prioritizing. 
- there could still be more improvements like having different user roles for people wanting a place to live and people looking to fill spaces in their existing accomodation, as well as discussing location, but we wanted to focus more on personality compatibility since your housemates are people you will most likely see every day and it's important to make that home environment as welcoming and supportive as possible whilst trying to take away the stress and anxiety that comes with living with new people!  




What's beyond the scope of the MVP: 
- user can go back and update information (will require recalibrating all the matched algorithm stuff so for now we'll keep initial preferences fixed however, we will set up the workflow for it)

- add a "price range" field : maybe one line that contains two sliders? So people looking for a place can specify the monetary range they're looking for and people looking to fill their vacancies already have a definite idea for how much it will cost them, so they will put a more narrower interval down. We just need to check to see if their price interval falls inside the price range of someone looking for housing. (vacancy filler user's range is a subset of house searcher's price range)

## Detected evidence (automated analysis)

Indexed codebase: 23 recognized source files, 63 KB.
- Firebase (technology) — detected in the code
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (27 of 27)

```
.gitignore
app.json
App.tsx
babel.config.js
index.ts
package.json
postcss.config.js
README.md
src/components/CustomCheckbox.tsx
src/components/MatchCard.tsx
src/components/Navbar.tsx
src/components/ProfileCard.tsx
src/config/firebase.ts
src/config/users.ts
src/context/ProfileContext.tsx
src/navigation/AppNavigator.tsx
src/screens/CheckboxScreen.tsx
src/screens/EditProfileScreen.tsx
src/screens/LoginScreen.tsx
src/screens/MatchesScreen.tsx
src/screens/ProfileScreen.tsx
src/screens/SignUpScreen.tsx
src/screens/SliderScreen.tsx
src/screens/SwipesScreen.tsx
src/types/nw.d.ts
tailwind.config.js
tsconfig.json
```

### Dependencies

- package.json: @babel/core@^7.26.10, @babel/preset-env@^7.26.9, @babel/preset-react@^7.26.3, @react-native-community/checkbox@^0.5.17, @react-native-community/slider@4.5.5, @react-navigation/native@^7.1.6, @react-navigation/native-stack@^7.3.10, @types/react@~18.3.12, autoprefixer@^10.4.21, babel-preset-expo@^12.0.11, expo@~52.0.43, expo-image-picker@^16.0.6, expo-linear-gradient@~14.0.2, expo-status-bar@~2.0.1, firebase@^11.6.0, lodash@^4.17.21, nativewind@^4.1.23, postcss@^8.5.3, react@18.3.1, react-icons@^5.5.0, react-native@0.76.9, react-native-deck-swiper@^2.0.17, react-native-paper@^5.13.1, react-native-safe-area-context@4.12.0, react-native-screens@~4.4.0, react-native-svg@^15.11.2, react-native-svg-transformer@^1.5.0, react-native-vector-icons@^10.2.0, tailwindcss@^3.4.17, typescript@^5.3.3

### Recent commits (newest first)

- updated readme
- fix: profile image upload not affecting other slider data anymore! I hope
- feat: matches are accurately shown (one can hope)
- Merge pull request #4 from Techgirl2/crunch-time-for-swiping
- finished the swipe screen. adds users to the left or right subarray in database after swiping. some weird slow rendering. haven't taken into account matching yet
- Merge pull request #3 from Techgirl2/Fixing-UI-Bugs
- fixed ui bugs for edit profile screen
- Merge branch 'main' of https://github.com/Techgirl2/BananaBunks
- links to icons on the bottom
- Merge pull request #2 from Techgirl2/Finishing-Up-Routing
- finished routing i think
- Merge pull request #1 from Techgirl2/Creating-Routes+Page-Formatting
- updates home screens
- feat: all data being stored in the database, including profile picture data being stored in firestore, just need to fix routing and alignment
- feat: database being populated with initial values, still need to solidify submit button
- made ui for match card, nav bar, and finished matches screen
- chore: removed local state, used global profile context
- finished first two pages. some state issues
- added a route for checkbox screen whichis part 2 of creating your profile
- made first profile screen. figuring out svg

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

### package.json

```
{
  "name": "bananabunks",
  "version": "1.0.0",
  "main": "index.ts",
  "scripts": {
    "start": "npx expo start --tunnel",
    "web": "npx expo start --web",
    "android": "npx expo start --android"
  },
  "dependencies": {
    "@react-native-community/checkbox": "^0.5.17",
    "@react-native-community/slider": "4.5.5",
    "@react-navigation/native": "^7.1.6",
    "@react-navigation/native-stack": "^7.3.10",
    "expo": "~52.0.43",
    "expo-image-picker": "^16.0.6",
    "expo-status-bar": "~2.0.1",
    "firebase": "^11.6.0",
    "lodash": "^4.17.21",
    "react": "18.3.1",
    "react-icons": "^5.5.0",
    "react-native": "0.76.9",
    "react-native-deck-swiper": "^2.0.17",
    "react-native-paper": "^5.13.1",
    "react-native-safe-area-context": "4.12.0",
    "react-native-screens": "~4.4.0",
    "react-native-svg": "^15.11.2",
    "react-native-vector-icons": "^10.2.0",
    "expo-linear-gradient": "~14.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.26.10",
    "@babel/preset-env": "^7.26.9",
    "@babel/preset-react": "^7.26.3",
    "@types/react": "~18.3.12",
    "autoprefixer": "^10.4.21",
    "babel-preset-expo": "^12.0.11",
    "nativewind": "^4.1.23",
    "postcss": "^8.5.3",
    "react-native-svg-transformer": "^1.5.0",
    "tailwindcss": "^3.4.17",
    "typescript": "^5.3.3"
  },
  "private": true
}

```

### App.tsx

```typescript
// App.tsx
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import AppNavigator from './src/navigation/AppNavigator';

export default function App() {
  return (
      <AppNavigator />
  );
}
```

### index.ts

```typescript
import { registerRootComponent } from 'expo';

import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

```

### postcss.config.js

```javascript
module.exports = {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
}

```

### babel.config.js

```javascript
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [],
  };
};

```

### tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.{js,jsx,ts,tsx}",
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

```

### src/types/nw.d.ts

```typescript
/// <reference types="nativewind/types" />

```

### src/config/users.ts

```typescript
import { doc, setDoc } from 'firebase/firestore';
import { db } from './firebase';

export const createUserProfile = async (uid: string, profileData: any) => {
  try {
    const userRef = doc(db, 'users', uid);
    await setDoc(userRef, profileData);
    console.log('User profile created!');
  } catch (error) {
    console.error('Error creating user profile:', error);
  }
};
```

### src/config/firebase.ts

```typescript
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "AIzaSyD9sElv3ATPC7xEgJuGL6-dleTB3acFIq8",
  authDomain: "bananabunks.firebaseapp.com",
  projectId: "bananabunks",
  storageBucket: "bananabunks.firebasestorage.app",
  messagingSenderId: "726999940763",
  appId: "1:726999940763:web:d6fb65b5ede4a739a8903e"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Init services
export const auth = getAuth(app);
export const db = getFirestore(app);
export const storage = getStorage(app);
```

### src/components/CustomCheckbox.tsx

```typescript
import React from 'react';
import { TouchableOpacity, Text, View, StyleSheet, ViewStyle, StyleProp } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

type CustomCheckboxProps = {
  label: string;
  checked: boolean;
  onPress: () => void;
  style?: StyleProp<ViewStyle>; // use StyleProp so it works well
};

export default function CustomCheckbox({ label, checked, onPress, style }: CustomCheckboxProps) {
  return (
    <TouchableOpacity style={[styles.container, style]} onPress={onPress}>
      <View style={[styles.checkbox, checked && styles.checked]}>
        {checked && <Ionicons name="checkmark" size={16} color="white" />}
      </View>
      <Text style={styles.label}>{label}</Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 20,
  },
  checkbox: {
    width: 24,
    height: 24,
    borderRadius: 6,
    borderWidth: 2,
    borderColor: '#FFB057',
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 12,
  },
  checked: {
    backgroundColor: '#FFB057',
  },
  label: {
    fontSize: 16,
    color: '#333',
  },
});

```

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