Description
Problem 1: Create the Photo Sharing Application
As starter code for your PhotoApp we provide you a skeleton ( photo-share.html which loads photoShare.jsx ) that can be started using the URL “http://localhost:3000/photo-share.html” (http://localhost:3000/photo-share.html). The skeleton:
Loads a ReactJS (https://reactjs.org/) web application that uses Material-UI (https://material-ui.com) to layout a Master-Detail pattern as described in class. It has a header made from a Material-UI App Bar (https://material-ui.com/demos/app-bar) accross the top, places a UserList component along the side, and has a content area beside it with either a UserDetail or UserPhotos components.
Uses the React Router (https://reacttraining.com/react-router/) to enable deep linking for our single page application by con guring routes to three stubbed out components:
- /users is routed to the component UserList in components/userList/
- /users/:userId is routed to the component UserDetail in components/userDetail/
- /photos/:userId is routed to the component UserPhotos in components/userPhotos/
See the use of HashRouter (https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md), and Route (https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md) in photoShare.jsx for details. For the stubbed out components in components/* , we provide an empty CSS le and a simple render function that includes some description of what it needs to do and the model data to use.
For this problem, we will continue to use our magic cs142models hack to provide the model data so we display a pre-entered set of information. As before, the models can be accessed using window.cs142Models . The schema of the model data is de ned below.
Your assignment is to extend the skeleton into a working web app operating on the fake model data. Since the skeleton is already wired to either display components UserList , UserDetail , and UserPhotos with the appropriate parameters passed by React Router, most of the work will be implementing the stubbed out components. They should be lled in so that:
components/userList component should provide navigation to the user details of all the users in the system. The component is embedded in the side bar and should provide a list of user names so that when a name is clicked, the content view area switches to display the details of that user.
components/userDetail component is passed a userId in the props.match by React Router. The view should display the details of the user in
a pleasing way along with a link to switch the view area to the photos of the user using the UserPhotos component.
components/userPhotos component is passed a userId , and should display all the photos of the speci ed user. It must display all of the photos
belonging to that user. For each photo you must display the photo itself, the creation date/time for the photo, and all of the comments for that photo. For each comment you must display the date/time when the comment was created, the name of the user who created the comment, and the text of the comment. The creator for each comment should be a link that can be clicked to switch to the user detail page for that user.
Besides these components, you need to update the TopBar component in components/topBar as follows:
The left side of the TopBar should have your name.
The right side of the TopBar should provide app context by re ecting what is being shown in the main content region. For example, if the main content is displaying details on a user the toolbar should have the user’s name. If it is displaying a user’s photos it should say “Photos of ” and the user’s name.
The use of ReactRouter in the skeleton we provide allows for deep-linking to the di erent views of the application. Make sure the components you build do not break this capability. It should be possible to do a browser refresh on any view and have it come back as before. Our standard approach to building components handles deep-linking automatically. Care must be taken when doing things like sharing objects between components. A quick browser refresh test on each view will show when you broke something.
Although you don’t need to spend a lot of time on the appearance of the app, it should be neat and understandable. The information layout should be clean (e.g., it should be clear which photo each comment applies to).
Photo App Model Data
For this problem we keep the magic DOM loaded model data we used in the previous project. The model consists of four types of objects: user , photo , comment , and SchemaInfo types.
Photos in the photo-sharing site are organized by user. We will represent users as an object user with the following properties:
| _id: | The ID of this user. |
| rst_name: | First name of the user. |
| last_name: | Last name of the user. |
| location: | Location of the user. |
| description: | A brief user description. |
| occupation: | Occupation of the user. |
The DOM function window.cs142models.userModel(user_id) returns the user object of the user with id user_id . The DOM function window.cs142models.userListModel() returns an array with all user objects, one for each the users of the app. Each user can upload multiple photos. We represent each photo by a photo object with the following properties:
| _id: | The ID for this photo. |
| user_id: | The ID of the user who created the photo. |
| date_time: | The date and time when the photo was added to the database. |
| le_name: | Name of a le containing the actual photo (in the directory project5/images ). |
| comments: | An array of the comment objects representing the comments made on this photo. |
The DOM function window.cs142models.photoOfUserModel(user_id) returns an array of the photo objects belonging to the user with id user_id .
For each photo there can be multiple comments (any user can comment on any photo). comment objects have the following properties:
| _id: | The ID for this comment. |
| photo_id: | The ID of the photo to which this comment belongs. |
| user: | The user object of the user who created the comment. |
| date_time | The date and time when the comment was created. |
| comment | The text of the comment. |
For testing purposes we have SchemaInfo objects have the following properties:
_id: The ID for this SchemaInfo.
__v: Version number of the SchemaInfo object. load_date_time:The date and time when the SchemaInfo was loaded. A string.
Problem 2: Fetch model data from the web server
After doing Problem 1, our photo sharing app front-end is looking like a real web application. The big barrier to be considered real is the fakery we are doing with the model data loaded as JavaScript into the DOM. In this Problem we remove this hack and have the app fetch models from the web server as would typically be done in a real application.
The webServer.js given out with this project reads in the cs142Models we were loading into the DOM in Problem 1 and makes them available using ExpressJS (http://expressjs.com) routes. The API exported by webServer.js uses HTTP GET requests to particular URLs to return the cs142Models models. The HTTP response to these GET requests is encoded in JSON. The API is:
/test/info – Returns cs142models.schemaInfo() . This URL is useful for testing your model fetching method.
/user/list – Returns cs142models.userListModel() .
/user/:id – Returns cs142models.userModel(id) .
/photosOfUser/:id – Returns cs142models.photoOfUserModel(id) .
You can see the APIs in action by pointing your browser at above URLs. For example, the links “http://localhost:3000/test/info”
(http://localhost:3000/test/info) and “http://localhost:3000/user/list” (http://localhost:3000/user/list) wiil return the JSON-encoded model data in the browser’s window.
To convert your app to fetch models from the web server you should implement a FetchModel function in lib/fetchModelData.js . The function should be declared as follows:
Although there many modules that would make implementing this function trivial, we want you to learn about the low-level details of AJAX. You may not use other libraries to implement FetchModel; you must write Javascript code that creates XMLHttpRequest DOM objects and responds to their events.
Your solution needs to be able to handle multiple outstanding FetchModel requests. To demonstrate your FetchModel routine works, your web application should work so that visiting http://localhost:3000/photo-share.html displays the version number returned by sending an AJAX request to the http://localhost:3000/test/info URL. The version number should be displayed in the TopBar component of your app.
After successfully implementing the FetchModel function in lib/fetchModelData.js , you should modify the code in
components/userDetail/UserDetail.jsx components/userList/UserList.jsx components/userPhotos/UserPhotos.jsx to use the FetchModel function to request the data from the server. There should be no accesses to window.cs142models in your code and your app should work without the line in photo-share.html :




