Skip to content

Starca is a storage marketplace that allows users to list their unused space to make extra income or look for storage listings so they can store their extraneous items.

Notifications You must be signed in to change notification settings

Nova-Storage/starca

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Starca

GitHub milestone GitHub milestone GitHub milestone GitHub milestone

Sprint MVP Walkthrough

Table of Contents

  1. Overview
  2. Product Spec
  3. Wireframes
  4. Schema
  5. Walkthroughs

Overview

Description

Starca is a storage marketplace that allows users to either list their unusued space to make some extra income or look for listed places so they can store items that are cluttering their spaces.

App Evaluation

  • Category: P2P Marketplace
  • Mobile: This app is being primarily developed for mobile but would perhaps be just as usable on a computer, similarly to Zillow, Apartments, etc. Mobile version would provide for better features and prove to be more convenient, as you would want to search/manage rental properties while not constricted to a computer.
  • Story: Allow landlords to post unused storage spaces for tenants to search for. Connects people looking to rent their storage space and people who are looking for a storage space at a rate best for them.
  • Market: Individuals that are looking to make some extra income by renting out unused space and those that need to clear up space in their house but don't want to pay the high prices for traditional storage facilities
  • Habit: This app is not meant to be used consistently. Renters and rentees can "set it and forget it"
  • Scope: Start by allowing users to post their storage spaces for rent and allowing users to search for storage spaces. Provide a platform for these two user groups to connect.

Product Spec

1. User Stories (Required and Optional)

Required Must-have Stories

  • Users will be able to register an account
  • Users will be able to log in to their account
  • Users will be able to view listings of storage places to rent nearby
  • Users will be able to view listings in other selected areas
  • Users will be able to post listings
    • Users will be able to post a picture (implicit intent) for listings
    • User will be able post details on their storage listing
  • Users will be able to update their profile
  • Users will be able to delete their account
  • User will have a profile page and will be able to view listings they own
  • Users will be able to view listings they are renting
  • User will be able to rate owner and listing
  • User will be able to click on a listing to view more details
  • Users will be able to chat with their prospective renters/rentees
  • User will be able to request to rent a listing
  • Owners will be prompted when a user wants to rent their listing
  • User will be prompted to accept the rental once the owner accepts a request

Optional Nice-to-have Stories

  • User will be able to block other users
  • User will be able to view previously rented storage listing
  • PayPal payment
  • User will be able to click "forgot password" to recover their password
  • (Live Messaging) User will be able to see a message pop up automatically once it is received from another user
  • Highly rated users will have an icon denoting their high rating next to their profile pictures
  • User can disable maps in dashboard
  • User will have to verify their email address
  • User will see the average response time of the owners they are trying to rent from
  • User will be able to sign in with Google
  • User will see a custom alert dialog
  • User will be able to sign in with Facebook
  • User will be able to post multiple pictures for listings
  • User will be able to cancel their rental

2. Screen Archetypes

  • Login
    • Users can log into their account
  • Register
    • Users can register for an account
  • Dashboard (Maps)
    • Users will see a maps screen that displays nearby listings to their current location, and a list of the listings below it with some more details for each property.
  • Listing Creation
    • Users will be able to post listings to the app
    • Fragment 1
      • Users upload pictures of their space
    • Fragment 2
      • Users enter details of the property (address
    • Fragment 3
      • Users enter more details (amenaties, etc) into the listing
  • Listing Detail
    • Show property details for a listing (Zip Code, photos, amenaties)
    • Show reviews for the property left by other users.
  • Messaging (Stream)
    • Display all the users that have been messaged
  • Messaging Detail Page
    • Display the messages two users have sent to each other. Allow a user to send a message to another user.
  • Profile
    • Users can add or change their profile photo
    • Users can see reviews about them left by other users.
  • Settings
    • Users can delete their account
    • Users can log out of their account

3. Navigation

Tab Navigation (Tab to Screen)

  • Dashboard
  • Create Listing
  • Message
  • Profile

Flow Navigation (Screen to Screen)

  • Home
    • Login - Bottom Nav
      • Dashboard
    • Register - Bottom Nav
      • Dashboard
  • Dashboard + Search
    • Search
      • Details
    • Details
    • Create Listing - Bottom Nav
      • Create Listing
    • Message - Bottom Nav
      • List of message
        • Message
      • Message
    • Profile - Bottom Nav
      • Settings

Wireframes

[BONUS] Digital Wireframes & Mockups

[BONUS] Interactive Prototype

Schema

Models

User

Property Type Desecription
objectID String Unique ID for the user
emailVerified Boolean Boolean indicating if the account was verified by user
createdAt Date Date when user was created
username String User's username created during registration
password String User's password created during registration
email String User's email
firstName String User's full name
lastName String User's full name
bio String User's self set bio
rating Number User's rating based on other user reviews

Image

Property Type Desecription
objectID String Unique ID of the uploaded image
image File Image that the user uploaded
listingID Pointer to Listing Listing the image was uploaded to

Listing

Property Type Desecription
objectID String Unique ID of the uploaded image
createdAt Date Date when user was created
userID Pointer to User User that created the Listing
title String The title of the listing
description String The description of the listing
addressStreet String The street address of the listing
addressZip String The zip code of the address
addressState String The state of the address
addressCity String The city of the address
amenities String Array Array of all the amenities

Message TBD

Networking

  • Login
    • (Read/GET) Query user
private fun loginUser(username: String, password: String) {
	ParseUser.logInInBackground(username, password, ({ user, e ->
		if (user != null) {
			Log.i(TAG, "Successfully logged in user")
			goToMainActivity()
		} else {
			e.printStackTrace()
			Toast.makeText(this, "Error logging in", Toast.LENGTH_SHORT).show()
		}
	}))
}
  • Register
    • (Create/POST) Create user
private fun registerUser(username: String, 
			  password: String, 
			  firstName: String, 
			  lastName: String, 
			  email: String) {

	val user = ParseUser()

	user.username = username
	user.setPassword(password)
	user.firstName = username
	user.lastName = username
	user.email = username

	user.signUpInBackground { e ->
		if (e == null) {
			// User successfully created new account
			Log.i(TAG, "User successfully registered")
			goToMainActivity()
		} else {
			Toast.makeText(this, "Error registered", Toast.LENGTH_SHORT).show()
			e.printStackTrace()
		}
	}
}
  • Creation
    • (Create/POST) Create a new listing
fun createListing(title: String, 
		  description: String, 
		  user: ParseUser, 
		  file: File, 
		  addressStreet: String, 
		  addressCity: String, 
		  addressState: String, 
		  addressZip: String, 
		  amenities: String) {

	val post = Post()
	post.setTitle(title)
	post.setDescription(description)
	post.setUser(user)
	post.setAddressStreet(addressStreet)
	post.setAddressCity(addressCity)
	post.setAddressState(addressState)
	post.setAddressZip(addressZip)
	post.setImage(ParseFile(file))

	post.saveInBackground { exception ->
		if (exception != null) {
			Log.e(MainActivity.TAG, "Error while saving post")
			exception.printStackTrace()
			Toast.makeText(requireContext(), "Couldn't save post", Toast.LENGTH_SHORT).show()
		} else {
			Log.i(MainActivity.TAG, "Successfully saved post")
			progressBar?.visibility = View.GONE
			etDescription.text.clear()
			Toast.makeText(requireContext(), "Listing Created!", Toast.LENGTH_SHORT).show()
		}
	}
}
  • (Create/POST) Upload image for a listing
fun uploadImage(listingID: String, file: File) {

	val image = Image()
	post.setListingID(listingID)
	post.setImage(ParseFile(file))

	image.saveInBackground { exception ->
		if (exception != null) {
			Log.e(MainActivity.TAG, "Error while uploading image")
			exception.printStackTrace()
			Toast.makeText(requireContext(), "Couldn't upload Image", Toast.LENGTH_SHORT).show()
		} else {
			Log.i(MainActivity.TAG, "Successfully uploaded image")
			progressBar?.visibility = View.GONE
			etDescription.text.clear()
			Toast.makeText(requireContext(), "Saved Image!", Toast.LENGTH_SHORT).show()
		}
	}
}
  • Maps Screen
    • (Read/GET) Query all listing location posts in database
    val query: ParseQuery<Post> = ParseQuery.getQuery(Post::class.java)
    
    query.addDescendingOrder("createdAt")
    query.findInBackground { posts, e ->
        if (e != null) {
            Log.e(TAG, "Error fetching posts.")
        } else {
            if (posts != null) {
                // retrieve post and populate map markers + recyclerView date.
                feedPosts.addAll(posts)
                adapter.notifyDataSetChanged()
            }
        }
    }
  • Messaging
    • (Read/GET) Query all Message requests addressed to user as well as their latest message.
    val query: ParseQuery<Post> = ParseQuery.getQuery(MessageRequest::class.java)
    
    query.addDescendingOrder("createdAt")
    query.findInBackground { message_requests, e ->
        if (e != null) {
            Log.e(TAG, "Error fetching posts.")
        } else {
            if (message_requests != null) {
                // retrieve dm from dm history and populate rv
                messages.addAll(message_requests)
                adapter.notifyDataSetChanged()
            }
        }
    }
  • (Delete) Delete existing Message
ParseQuery<ParseObject> query = ParseQuery.getQuery("message_requests");

query.getInBackground("<PARSE_OBJECT_ID_ofMessage>", (object, e) -> {
  if (e == null) {
	object.deleteInBackground(error -> {
		if(error==null){
			//item delete. send confirmation info to user
		}else{
			//error deleting obj. send something to user.
		}
	});
  }else{
	//error. message doesn't exist. let user know
  }
});
  • Conversation
    • (Create/POST) Create a new message
val query: ParseQuery<Post> = ParseQuery.getQuery(DirectMessage::class.java)

query.addDescendingOrder("createdAt")
query.findInBackground { dms, e ->
	if (e != null) {
		Log.e(TAG, "Error fetching dms.")
	} else {
		if (dms != null) {
			// retrieve dms and populate conversations rv
			direct_messages.addAll(posts)
			adapter.notifyDataSetChanged()
		} else {
			Log.e(TAG, "Error fetching dms.")
		}
	}
}
  • Detail
    • (Read/GET) Query Post data/info
ParseQuery<ParseObject> query = ParseQuery.getQuery("posts");

query.getInBackground("<PARSE_OBJECT_ID_ofPost>", (post, e) -> {
	  if (e == null) {
	  //Object was successfully retrieved. display post data
	} else {
	  // error. post with id doesn't exist.
	}  
});
  • Profile
    • (Read/GET) Query Profile data
    • (Read/GET) Query Comments data
ParseQuery<ParseObject> query = ParseQuery.getQuery("profiles");

query.getInBackground("<PARSE_OBJECT_ID_ofProfile>", (profile, e) -> {
	  if (e == null) {
	  //Object was successfully retrieved. display profile info
	} else {
	  // error. profile with id doesn't exist.
	}  
});
  • Settings
    • (Read/GET) Query Settings data
ParseQuery<ParseObject> query = ParseQuery.getQuery("settings");

query.getInBackground("<PARSE_OBJECT_ID_ofProfile>", (profile, e) -> {
	if (e == null) {
	  //Object was successfully retrieved. get settings info from profile.settings
	} else {
	  // error. profile with id doesn't exist.
	}  
});
  • (Update/PUT) Modify Settings data
ParseQuery<ParseObject> query = ParseQuery.getQuery("profiles");

query.getInBackground("<PARSE_OBJECT_ID_ofProfile>", (settings, e) -> {
  if (e == null) {
	
	settings.put("bio_description", "a string");
	settings.put("username", "a string");
	settings.put("email", "a string");
	settings.put("phone number", "a string");
	settings.put("email_promotions", "a boolean");
	settings.put("email_dm_notifications", "a boolean");
	settings.put("email_payment_reminders", "a boolean");

	//All other fields will remain the same
	object.saveInBackground();

  } else {
	//error. profile not found 
  }  
});
  • (Delete) Delete Account data
ParseQuery<ParseObject> query = ParseQuery.getQuery("accounts");

query.getInBackground("<PARSE_OBJECT_ID_ofAccount>", (object, e) -> {
  if (e == null) {
	object.deleteInBackground(error -> {
		if(error==null){
			//item deleted. send confirmation info to user.
		}else{
			//error deleting obj. send something to user.
		}
	});
  }else{
	//error. account doesn't exist. let user know
  }
});

Walkthroughs

Sprint 1

Sprint 1 Walkthrough

Required stories

  • Users will be able to register an account
  • Users will be able to log in to their account
  • Users will be able to view listings of storage places to rent nearby
  • Users will be able to post listings
    • Users will be able to post a picture (implicit intent) for listings
    • User will be able post details on their storage listing
  • Users will be able to update their profile
  • Users will be able to delete their account

Stretch stories

  • User will have to verify their email address

Sprint 2

Sprint 2 Walkthrough

Required stories

  • Users will be able to view listings in other selected areas
  • User will have a profile page and will be able to view listings they own
  • User will be able to click on a listing to view more details
  • User will be able to request to rent a listing

Stretch stories

Sprint 3

Sprint 3 Walkthrough

Required stories

  • Users will be able to view listings they are renting
  • Users will be able to chat with their prospective renters/rentees
  • Owners will be prompted when a user wants to rent their listing
  • User will be prompted to accept the rental once the owner accepts a request

Stretch stories

  • User will see a custom alert dialog

Sprint 4

Sprint 4 Walkthrough

Required stories

  • User will be able to rate owner and listing

Stretch stories

  • User will be able to block other users
  • (Live Messaging) User will be able to see a message pop up automatically once it is received from another user
  • User will be able to cancel their rental

About

Starca is a storage marketplace that allows users to list their unused space to make extra income or look for storage listings so they can store their extraneous items.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •