Zoomm live is a photo sharing full-stack web application based closely on 500px. Zoomm allows users to publicly share their best photos in the elite photographer community. I created Zoomm using Ruby on Rails and React/Redux.
- Highly secure authentication for user login and signup
- Upload, edit, delete photos
- Setting personalized profile photo and cover photo in User Profile page
- Follow other users and their photos would show up in User Feed page
- Discover all the amazing photos brought by other great photographers in Zoomm community
The database store the BCrypt password_digest
instead of User's actual password.
I used SecureRandom
to ensure each user has an unique session_token
when they are signed in. Their session_token
resets when they sign out.
def password=(password)
@password = password
self.password_digest = BCrypt::Password.create(password)
end
def is_password?(password)
BCrypt::Password.new(self.password_digest).is_password?(password)
end
def reset_session_token
self.session_token = SecureRandom.urlsafe_base64
self.save!
self.session_token
end
I used ActiveRecord to query Photo table based off the user id sent from the frontend.
def index
if params[:id]
@photos = Photo.where("author_id = ?", params[:id])
else
@photos = Photo.all
end
render "api/photos/index"
end
I created a customized route for User's feed page.
def index_feed
@photos = [];
current_user.followings.each do |followee|
@photos.push(followee.photos)
end
@photos = @photos.flatten
render "api/photos/index"
end
Users can't visit /#/login
or /#/signup
routes if they are already logged in on the front-end.
const Auth = ({ component: Component, path, loggedIn, currentUser }) => (
<Route
path={path}
render={props =>
!loggedIn ? (
<Component {...props} />
) : (
<Redirect to={`/user/${currentUser.id}`} />
)}
/>
);
const Protected = ({ component: Component, path, loggedIn }) => (
<Route
path={path}
render={props =>
loggedIn ? <Component {...props} /> : <Redirect to="/login" />}
/>
);
const mapStateToProps = state => ({
loggedIn: Boolean(state.session.currentUser),
currentUser: state.session.currentUser
});
export const AuthRoute = withRouter(connect(mapStateToProps, null)(Auth));
export const ProtectedRoute = withRouter(
connect(mapStateToProps, null)(Protected)
);
I used Cloudinary to host photos storage. Users are able to upload photos. The upload form pops up using Modal, and it gives the preview for that photo, along with title and description input.
Zoomm was created utilizing these key technologies:
- jQuery
- Webpack
- React/Redux
- React DOM
- React Router
- React Modal
- Ruby on Rails
- PostgreSQL database
- Cloudinary image storage
User has the ability to like photos from Feed and Discover page, but not their own photos.
User has the ability to comment on photos from Feed and Discover page. User can also like or comment on the comments.
Each photo can have a maximum amount 10 tags, which will eventually be used to sort into different albums.
See the development for a list of components, sample state, DB schema, and wireframes.