# Project export: Dog Meets Dawg

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: A playdate app for Dogs
- Devpost: https://devpost.com/software/dog-meets-dawg
- GitHub: https://github.com/richard-dao/dog-meets-dawg
- Demo: http://dog-meets-dawg.tech/
- Team: 3 GitHub contributor(s) — Vinh (12 commits), Richard Dao (6 commits), anptruon (3 commits)

## Devpost submission (written by the team)

### Inspiration

That one movie where the dogs meet. You know what I'm talking about right? With the Cavaliers? Oh the movie is literally called "Puppy Love"

### What it does

It's Hinge for Dogs.

### How we built it

React-Native frontend AWS backend: Two APIs: WebSocket API and REST API Lambda functions for both APIs Messages are published to AWS SNS with a broadcaster lambda function subscriber DB: DynamoDB

### Challenges we ran into

Learning a whole lot of new technologies and tech stacks in a short amount of time

### Accomplishments we're proud of

We built a whole login/authentication system from scratch instead of using a pre-built solution (we probably should have used a pre-built solution LMAO) Overengineered the WebSocket real-time messaging to incorporate a AWS SNS publisher/subscriber model

### What we learned

React-Native AWS: API Gateway, Lambda, DynamoDB, SNS WebSocket protocols Authentication protocols

### What's next

Adding the ability to save images into a AWS S3 bucket to work as a CDN

## README (from the GitHub repository)

# Inspiration
That one movie where the dogs meet. You know what I'm talking about right? With the Cavaliers? Oh the movie is literally called "Puppy Love"

# What it does
It's Hinge for Dogs.

# How we built it

React-Native frontend AWS backend:

- Two APIs: WebSocket API and REST API
- Lambda functions for both APIs
- Messages are published to AWS SNS with a broadcaster lambda function subscriber
- DB: DynamoDB
# Challenges we ran into
- Learning a whole lot of new technologies and tech stacks in a short amount of time
# Accomplishments that we're proud of
- We built a whole login/authentication system from scratch instead of using a pre-built solution (we probably should have used a pre-built solution LMAO)
- Overengineered the WebSocket real-time messaging to incorporate a AWS SNS publisher/subscriber model
# What we learned
- React-Native
- AWS: API Gateway, Lambda, DynamoDB, SNS
- WebSocket protocols
- Authentication protocols
# What's next for Dog Meets Dawg
- Adding the ability to save images into a AWS S3 bucket to work as a CDN
# Built With
- amazon-sns
- amazon-web-services
- api-gateway
- dynamodb
- lambda
- react-native
- rest-api
- websockets
# Try it out
 GitHub Repo
 [dog-meets-dawg.tech](dog-meets-dawg.tech)


## Detected evidence (automated analysis)

Indexed codebase: 18 recognized source files, 36 KB.
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- AWS (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (24 of 24)

```
.dockerignore
.gitignore
App.js
app.json
components/DogCard.js
components/DogSwiper.js
context/MatchesContext.js
context/UserContext.js
dockerfile
index.js
navigation/BottomTabs.js
navigation/MainWrapper.js
package.json
README.md
run-expo.cmd
screens/ChatListScreen.js
screens/ChatRoomScreen.js
screens/LocationScreen.js
screens/LoginScreen.js
screens/ProfileScreen.js
screens/SignUpScreen.js
screens/SwiperScreen.js
services/api-endpoints.js
services/websocket.js
```

### Dependencies

- package.json: @babel/core@^7.20.0, @expo/metro-runtime@~4.0.1, @react-navigation/bottom-tabs@^7.3.10, @react-navigation/native@^7.1.6, @react-navigation/native-stack@^7.3.10, expo-image-picker@~16.0.6, expo-status-bar@~2.0.1, gh-pages@^6.3.0, lodash@^4.17.21, react@18.3.1, react-dom@18.3.1, react-native@0.76.9, react-native-deck-swiper@^2.0.17, react-native-gesture-handler@~2.20.2, react-native-reanimated@~3.16.1, react-native-safe-area-context@4.12.0, react-native-screens@~4.4.0, react-native-svg@15.8.0, react-native-vector-icons@^10.2.0, react-native-web@~0.19.13

### Recent commits (newest first)

- Initialize README with project details
- final
- Fixed
- Pushed dist
- Websocket and APIs connected
- updated redirect from sign in hopefully not broken
- fuck the buttons
- changed
- fixed swipe right
- Button and activity indictator changes
- added loader
- added updateAccount api and handling on profile page
- Made really ugly but works
- login and create account api endpoints added
- removed button
- meow
- Fixed Some Front End Stuff
- Added more features
- Added login page no backend yet and more user profile options
- End Display and Pages

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

### dockerfile

```
FROM node:18

RUN npm install -g expo-cli

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npx expo install react-dom react-native-web @expo/metro-runtime

EXPOSE 8081 19000 19001 19002

CMD ["npx", "expo", "start"]
```

### package.json

```
{
  "name": "dog-meets-dawg",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@expo/metro-runtime": "~4.0.1",
    "@react-navigation/bottom-tabs": "^7.3.10",
    "@react-navigation/native": "^7.1.6",
    "@react-navigation/native-stack": "^7.3.10",
    "expo-image-picker": "~16.0.6",
    "expo-status-bar": "~2.0.1",
    "lodash": "^4.17.21",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "react-native": "0.76.9",
    "react-native-deck-swiper": "^2.0.17",
    "react-native-gesture-handler": "~2.20.2",
    "react-native-reanimated": "~3.16.1",
    "react-native-safe-area-context": "4.12.0",
    "react-native-screens": "~4.4.0",
    "react-native-svg": "15.8.0",
    "react-native-vector-icons": "^10.2.0",
    "react-native-web": "~0.19.13"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "gh-pages": "^6.3.0"
  },
  "private": true
}

```

### index.js

```javascript
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);

```

### App.js

```javascript
import React, { useContext, useState } from 'react';
import { UserProvider, UserContext } from './context/UserContext';
import { MatchesProvider, MatchesContext } from './context/MatchesContext';
import LoginScreen from './screens/LoginScreen';
import SignUpScreen from './screens/SignUpScreen';
import BottomTabs from './navigation/BottomTabs';

export default function App() {
	return (
		<MatchesProvider>
			<UserProvider>
				<AppContent />
			</UserProvider>
		</MatchesProvider>
	);
}

const AppContent = () => {
	const { user } = useContext(UserContext);
	const [showSignUp, setShowSignUp] = useState(false);

	// Show Sign Up screen
	if (!user && showSignUp) {
		return <SignUpScreen goToLogin={() => setShowSignUp(false)} />;
	}

	// Show Login screen
	if (!user) {
		return (
			<LoginScreen
				onLogin={() => {
					// No action needed here, user context will update and trigger BottomTabs render
				}}
				goToSignUp={() => setShowSignUp(true)}
			/>
		);
	}

	// User is logged in → show main app
	return <BottomTabs />;
};

```

### services/websocket.js

```javascript
export const websocket_baseURL = 'wss://5zre0unk9g.execute-api.us-west-1.amazonaws.com/dev/';
```

### context/UserContext.js

```javascript
import React, { createContext, useState } from 'react';

export const UserContext = createContext();

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
};
```

### context/MatchesContext.js

```javascript
import React, { createContext, useState } from 'react';

export const MatchesContext = createContext();

export const MatchesProvider = ({ children }) => {
  const [matches, setMatches] = useState(null);

  return (
	<MatchesContext.Provider value={{ matches, setMatches }}>
	  {children}
	</MatchesContext.Provider>
  );
};
```

### screens/LocationScreen.js

```javascript
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const LocationScreen = () => (
  <View style={styles.container}>
    <Text style={styles.text}>Track Location 📍</Text>
  </View>
);

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  text: { fontSize: 24 },
});

export default LocationScreen;
```

### navigation/MainWrapper.js

```javascript
import React, { useContext } from 'react';
import { View, Button, SafeAreaView } from 'react-native';
import { UserContext } from '../context/UserContext';
import BottomTabs from './BottomTabs';

const MainWrapper = ({ onLogout }) => {
  const { setUser } = useContext(UserContext);

  const handleLogout = () => {
    setUser(null);
    onLogout();
  };

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <View style={{ paddingHorizontal: 20, paddingTop: 10 }}>
        <Button title="Log Out" onPress={handleLogout} color="#ff6b6b" />
      </View>
      <BottomTabs />
    </SafeAreaView>
  );
};

export default MainWrapper;
```

### components/DogSwiper.js

```javascript
import React, { useEffect } from 'react';
import Swiper from 'react-native-deck-swiper';
import { View, StyleSheet } from 'react-native';
import DogCard from './DogCard';

const DogSwiper = ({ dogs, swiperRef, onSwiped, onSwipedRight }) => {
	// Function to handle swipe events
	return (
		<View style={styles.swiperContainer}>
			<Swiper
				ref={swiperRef}
				cards={dogs}
				renderCard={(dog) =>
					<DogCard
						dogName={dog.dogName}
						dogAge={dog.dogAge}
						dogImage={dog.dogImage}
						dogBreed={dog.dogBreed}
						dogBio={dog.dogBio}
					/>
				}
				onSwiped={onSwiped} // ✅ Only handling general swipe
				onSwipedRight={onSwipedRight} // ✅ Only handling right swipe
				stackSize={3}
				backgroundColor={'#f0f0f0'}
				cardIndex={0}
				animateCardOpacity
				disableTopSwipe
				disableBottomSwipe
			/>
		</View>

	);
};

const styles = StyleSheet.create({
	swiperContainer: {
		flex: 1,
	},
});

export default DogSwiper;

```

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