Spacebook is a fullstack clone of Meta's social media website Facebook. The goal of this project was to successfully clone basic backend and frontend capabilities of the original site.
In the current implementation of Spacebook, a user is able given several features such as: account creation, demo login, login, and CRUD functionality for account information, posts, comments, friends, and likes. Users are also able to upload and delete photos for account profile pictures, cover photos, and post photos. All changes will persist across any account logged in. Data stored in the site currently was created using a seed file.
The backend of this project was accomplished using Ruby on Rails while the frontend was accomplished using React, React Redux, and ReactRouter version 5; projects dependencies were handled using npm. The live version of this webproject is hosted on Render.Furthermore, AWS S3 was used to store images used in this project.
Using rails with jbuilder, normaled backend data is formed as JSON responses which are sent over to the react frontend. Redux was used as data store, with slices of state made for several attributes such as users,posts,comments,likes,and friends. The data is then used in components created in react, with frontend routes made for different pages such as the home page and profile page. Styling was done with CSS and was done to match the style of the original site.
Spacebook matches the basic uses of Facebook. Users are able to post posts, make comments, and edit their profiles. Logged in users are able to edit and delete the following: profile photo, cover photo, comments, and posts that belong to them. Logged in users can also add and remove other users as friends. Thunk action creators (thunk is a middleware provided in react redux) were used to fetch data from the backend and parse it to a response in the components. Below is an example of a thunk action creator used to edit a user's information.
export const editUser = user => async dispatch =>{
const {firstName,lastName,email,password,gender,birthday,aboutMe} = user;
const res = await csrfFetch(`/api/users/${user.id}`,{
method: 'PATCH',
body: JSON.stringify({
user:{
firstName,
lastName,
email,
password,
gender,
birthday,
aboutMe
}
})
});
let userData = await res.json()
dispatch(receiveProfile(userData.user))
dispatch(receiveUser(userData.user))
storeCurrentUser(userData.user)
restoreSession()
return res
}
import {createStore,combineReducers,applyMiddleware,compose} from 'redux'
import thunk from 'redux-thunk'
import session from './session';
import users from './users'
import posts from './posts'
import friends from './friends'
import comments from './comments'
import likes from './likes'
export const rootReducer = combineReducers({
session,
users,
posts,
friends,
comments,
likes
})
let enhancer;
if (process.env.NODE_ENV === 'production') {
enhancer = applyMiddleware(thunk);
} else {
const logger = require('redux-logger').default;
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
enhancer = composeEnhancers(applyMiddleware(thunk, logger));
}
const configureStore = (preloadedState) =>{
return createStore(rootReducer,preloadedState,enhancer);
};
export default configureStore
const postsReducer = (state={},action) =>{
switch(action.type){
case RECEIVE_POSTS:
return {...action.posts}
case RECEIVE_POST:
return {...state,[action.post.id]:action.post}
case REMOVE_POST:
const newState = {...state}
delete newState[action.postId]
return newState
default:
return state
}
}
export default postsReducer
Add hovering effects to display more information on components such as likes, comments and posts.
For friending, send a request to give users chance to accept/refuse a friend request.
Live chat using websockets.
Allow resizing of profile and cover photos.
Add favoriting and other reactions.
Allow users to follow/unfollow other users to control what shows on the splash page.