├── .gitignore
├── DAY_FOUR_README.md
├── DAY_THREE_README.md
├── DAY_TWO_README.md
├── README.md
├── assets
├── InstaClone-componentStructure.jpg
├── folder_structure.png
├── ig_post.png
└── ig_search_bar.png
└── dummy-data.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 |
4 | .idea/
5 |
--------------------------------------------------------------------------------
/DAY_FOUR_README.md:
--------------------------------------------------------------------------------
1 | ## Day IV
2 |
3 | ### Focus (Day IV)
4 |
5 | - Be able to use styled-components to add functional styles to your React Components
6 | - Be able to explain why state driven views and components are useful patterns for scalability, composability, and reuse and how React enables those patterns
7 |
8 | ### Daily Setup (Day IV)
9 |
10 | - By now you have been working on laying out your application, adding functionality and even building out a login system that only shows your app if a user is logged in.
11 | - Today we're going to be adding `styled-components` to our application. For more on the motivation behind this approach watch this [styled-components](https://youtu.be/bIK2NwoK9xk).
12 |
13 | #### Tasks (Day IV)
14 |
15 | - Try and replace all of the styles you have previously written. Change everything to be a Styled Component. (Except for where you need to reference your icon classNames.)
16 |
17 | - Re-factor `SearchBar` to use `styled-components`.
18 | - Create a `Header` styled-component.header that wraps your entire SearchBar.
19 |
20 | - We recommend working left to right so begin changing out your styles on the instagram logo.
21 | - Create a `LogoHeader` styled-component.div
22 | - Create a `LogoImage` styled-component.img that fills in the background of your
23 |
24 | - Re-factor your `PostContainer` component use only styled components
25 |
26 | - Start with the `UserThumbnail` and `Username`
27 | - Note that the `Username` styles could most certainly be used by your `CommentSection` component as well.
28 | - To achieve this, you'll simply just build out your reusable `styled-component` inside of a `Styles/Reusables` directory. This is where you could store all of your reusable styled components and export them out of their respective files to then import them for reuse.
29 | - Notice that the `Username` on top of the Post is a bit bolder than the `Username`'s found in the comment section. If there is a way to make this reusable styled component accept a prop that will distinguish it from being now is the time to figure that out.
30 |
31 | - Now move onto the `CommmentSection` and get rid of any CSS that you don't need.
32 | - By now you're a pro at using `Styled-Components` and we hope you armed with the ammo necessary to choose whether or not you like using it as opposed to vanilla CSS or even a Pre-Processor. We don't want you to believe that there is never a time and place for both native CSS/Pre-processing to exist. But at least now you have a variety of weapons you can choose from to get the job done.
33 |
34 | - Now is the time to take a step back and look at what you have accomplished this week. Start from the Day 1 README file and see what the tasks were there? Think about how we asked you to approach this problem. Think about the different components you have built? Did you separate out your Comments array from the rest of the application state? If so, what types of advantages did you gain by doing so? React is a very powerful tool and the next steps in learning about the React Ecosystem will all revolve around other libraries that we will plug into our application for extending it's use.
35 |
36 | - Read [this article](https://dev.to/nimmo/state-driven-development-for-user-interfaces-part-1-an-introduction-27f1) about 'State Driven Views' and come up with a short paragraph as to why you feel that `state-driven` views are important to us as software developers today? What are state-driven applications? Why are they powerful? How does React enables those patterns?
37 |
38 | #### Stretch Problems (Day IV)
39 |
40 | - Add the functionality to select a single Post. If a user clicks on a post, only show that post.
41 | - You will need to research into `React Router V. 4` (this is what we're learning about next week) to get this to work in a fluid fashion.
42 | - Be sure to declare routes for your home `/` page (`` or ``);
43 | - Declare a Route for `/single-post` and mount the single post that the user clicks on.
44 |
--------------------------------------------------------------------------------
/DAY_THREE_README.md:
--------------------------------------------------------------------------------
1 | ## Day III
2 |
3 | ### Focus (Day III)
4 |
5 | - Be able to explain and implement a React Higher Order Component to conditionally render protected content to the screen.
6 |
7 | ### Daily Setup (Day III)
8 |
9 | - To start off today, your application should still be structured like yesterday, but now it should have a working search bar, comment input, and like icon.
10 | - Those aren't necessary, however, for what you will be doing today. You can still work on today's part of this project even if you aren't completely done with yesterday's portion.
11 |
12 | ### Description (Day III)
13 |
14 | - Today you will be building a "Higher Order Component" (HOC)
15 | - The HOC will not let users see the posts until they have logged in. (Our login system for this will be faked using LocalStorage).
16 | - The job of the HOC will be to render a login page if the user is not logged in, then render the posts after the user is logged in.
17 |
18 | #### Tasks (Day III)
19 |
20 | - Create a `` component in your `components/PostsContainer` directory.
21 |
22 | - You'll have to move a lot of what is rendered in `app.js` to this new component
23 | - In app.js, render the `PostsPage` component.
24 | - Make sure the app working as it was before since it has been re-factored now.
25 | - This is to ensure that we clean up our App component a little bit before we re-factor it to be wrapped up in an HOC
26 |
27 | - Building the High Order Component
28 |
29 | - Create a directory called `authentication`
30 | - Inside that directory create a HOC called `withAuthenticate`. This is where all of the magic is going to happen.
31 | - This component should be able to take in a component as an argument, and it will return a `class` component.
32 | - Inside of `withAuthenticate's` render method, you'll want to return the Component that gets passed into it.
33 | - Be sure to export.
34 | - Head over to App.js and `import` in our new `withAuthenticate` Higher Order Component.
35 | - Set a new const called `ComponentFromWithAuthenticate`, and set it's value to the HOC invoked, with `PostsPage` passed in.
36 | - Inside `App`, you should now render `ComponentFromWithAuthenticate` in place of `PostsPage`.
37 | - If this worked correctly, then everything should render as it used to.
38 | - `withAuthenticate` will look a lot like this when you're done setting it up.
39 |
40 | ```js
41 | const withAuthenticate = App =>
42 | class extends React.Component {
43 | render() {
44 | return ;
45 | }
46 | };
47 | ```
48 |
49 | - Build out the LoginPage component. You can design it how you like
50 |
51 | - In your `components` directory, create a directory called `Login` and add a new file called `Login.js`.
52 | - There should be a `username` input, a `password` input, and a `Login` button.
53 | - The component should invoke the `login` function in `Login.js` when a user logs in.
54 | - This login function should set a `username` on `localStorage`. You'll need to check local storage to see if a user is logged in.
55 | - Be sure to force the page to reload when a user logs in so that our component un-mounts and mounts again.
56 |
57 | - Extending the functionality of the HOC to conditionally render the `LoginPage` or the `App`
58 |
59 | - First, we need to change our `withAuthenticate` HOC to return a second function that will take in a second component (which will be the `LoginPage`). This will look like a "double arrow" function - `const withAuthenticate = PostsPage => LoginPage => {}`.
60 | - In `App.js`, we can now invoke the HOC function twice (which is called currying). The first time it's invoked, pass in `PostsPage`. The second time, pass in `LoginPage` (which you'll need to import here). ie - `export default higherOrderComp(FirstComponent)(SecondComponent)`
61 | - Inside of the class component that the inner function in `withAuthenticate` returns, we need to add a constructor to hold our state data.
62 | - On state we need a `loggedIn` boolean flag.
63 | - In `componentDidMount` we need to check `localStorage` to see if a user is logged in, and setState accordingly.
64 | - Inside of the render function we will check `if a user is logged in` from the state boolean flag
65 | - If a user is logged in we will return the ``, else we will return the ``
66 |
67 | #### Stretch Problems (Day III)
68 |
69 | - Now that you have a user set in `localStorage`, go ahead and use that `username` when a user posts a comment to make it so the logged in user is the one commenting on the posts.
70 | - Styled-Components
71 |
72 | - Watch this video about [styled-components](https://youtu.be/bIK2NwoK9xk) in its entirety.
73 | - Head over to the [Styled-Components docs](https://www.styled-components.com/) and learn about the library.
74 | - Once you feel like you've got a good grasp of this concept, go ahead and start converting your components into styled-components.
75 | - Try and make this thing as beautiful as possible
76 |
77 | - Deploy your Instagram clone to netlify and share it in the #show-it-off channel.
78 |
--------------------------------------------------------------------------------
/DAY_TWO_README.md:
--------------------------------------------------------------------------------
1 | ## Day II
2 |
3 | ### Focus (Day II)
4 |
5 | - Understand the concept of React component lifecycles, along with the major lifecycle methods such as `render`, `componentDidMount`.
6 |
7 | ### Daily Setup (Day II)
8 |
9 | - At this point you should have a working app with a component tree that is setup kind of like this (note that this is not a design spec!):
10 |
11 |
12 |
13 | - Your data should be imported to `app.js`, and then passed as props to each `PostContainer`.
14 | - Each `PostContainer` should then be passing data to a `CommentSection` via props as well.
15 | - The props being passed to each component should be typed checked using `propTypes` and `defaultProps`.
16 | - The comment section should add a comment to the post
17 |
18 | ### Description (Day II)
19 |
20 | - For this part of the project you are going to use React's lifecycle methods to get data and to render the components. Then you will use functions passed as props to build out the functionality more.
21 | - As data comes into the component, you will set it to the component's state, then pass it down to the child components.
22 | - Add the functionality to add a comment to any of the posts. Since there is no login page or anything of that sort, hard code a static username.
23 | - Implement the ability to like a post by clicking on a heart icon and having the number of likes increment accordingly.
24 | - Get the Search Bar to filter posts by the post's username. When you submit a search term should filter out posts by users whose usernames do not match the search term.
25 |
26 | #### Tasks (Day II)
27 |
28 | - Use lifecycle methods
29 | - In `App.js` use `componentDidMount()` to set your data to the component's state. This dummy data held in state is an array you can map over, and output a `PostContainer` for each element in the array. Make sure to inject the right props into each `PostContainer` component.
30 | - Adding comments
31 | - Lets divide up the data that we've been working with this far by separating the comments array onto a new component's state. Pass down the comments through each post to the CommentSection component. Be sure that you set the incoming `comments` props data on the state of the CommentSection component.
32 | - Create a function in `App.js` called `addNewComment` that takes in an event and a post id. The function will add the comment contained inside the event object to the post with the given id. Alternatively, you can use the index number of the post instead of its id.
33 | - Pass the `addNewComment` function down the component tree to where ever you have your 'Add a comment...' input.
34 | - The 'Add a comment...' input should be wrapped in a `` element. Using that form's `onSubmit` event handler, invoke the `addNewComment` function and pass it the required arguments it needs to add a new comment.
35 | - Update your state with the new comment (This should trigger your component tree to "re-render" with your new comment on that post).
36 | - Liking posts
37 | - This will be set up a lot like the 'Add a comment...' input. Pass a function down to where your heart icon is, and use `onClick` event handler to increment that post's likes.
38 | - Search
39 | - Set up the search bar like the comment input and the like button. In your function, filter out any post whose username doesn't match the search term passed in, then update the state with the resulting data.
40 |
41 | #### Stretch Problems (Day II)
42 |
43 | - Persist your data using `localStorage`. If done correctly, you will be able to refresh your page and still see your new comments.
44 | - Add the ability to delete a comment from your data. If your data is in `localhost`, make sure to delete it from there as well.
45 | - Implement a third-party library that does "fuzzy" searches into your search bar functionality (ie - search terms that aren't exact, like "phils" or "coffeephilz", would still return the username "philzcoffe").
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React-Insta-Clone
2 |
3 | ## Introduction
4 |
5 | - The purpose of this project is to continue building on your knowledge of React that you have gained thus far.
6 |
7 | - Here, you'll be implementing a lot of the same concepts that you have been in previous projects, in a very similar fashion.
8 | - The main difference this time around is that you'll be using the `create-react-app (CRA)` utility to generate your React project for you.
9 | - Don't worry about all of the extra files that you may not understand which will be present inside your React application that you will build with CRA.
10 | - The overall structure of the project remains exactly the same as what you worked with in Todo-React.
11 |
12 | - This project will be worked on throughout the entire week.
13 |
14 | - Each day as you learn new things, you will use that knowledge to build and enhance this project a little more.
15 | - You will use the same repo throughout the whole week, adding more code, and changing things here and there as you learn new principles and techniques.
16 | - It will be important to communicate any problems you're having to your Project Manager so that we can make sure to get you un-stuck along the way as soon as possible.
17 | - The goal is to finish each day's objectives, and have a working project to start with on the next day.
18 | - If you don't get the daily objectives, don't panic, some days will be easier for you than others and some days will be harder.
19 | - The hope is that by the end of the week, you'll have seen a react application come to life, and you'll start to see how react works at a higher level.
20 |
21 | - For this project, you'll be building a simple Instagram clone using React.
22 | - There is a file provided called `dummy-data.js` that contains some mock data. Each object in the mock data represents a faux Instagram post.
23 | - Your React application will receive faux post data and render each as a separate Instagram post.
24 |
25 | ## Day I
26 |
27 | ### Focus (Day I)
28 |
29 | - Demonstrate the the ability to use create-react-app to boilerplate a react application
30 | - Describe and be able to use PropTypes to 'type check' specific data being passed down to a child component
31 | - Demonstrate the ability to use defaultProps in a React component
32 |
33 | ### Project Setup
34 |
35 | - Create a React application by running `npx create-react-app instagram-app` from inside this directory.
36 | - cd into `instagram-app`
37 | - Create a `components` directory inside the `src` directory, and then create a sub-directory called `SearchBar`, another one called `PostContainer`, and lastly one called `CommentSection`, all inside the `src` directory. Each of these directories should contain the component file as well as the CSS for their respective components. You'll also want to put any other components that coincide with your respective container components inside of these directories.
38 |
39 | ### Tasks (Day I)
40 |
41 | - There are three major container components that you'll need to implement for this project: the Search Bar, the Post Container, and the Comment Section.
42 | - At the end of Day I there will be a single instance of the Search Bar being rendered at the top of the page, as well as a Post Container and a Comment Section for every piece of mock data in the `dummy-data.js` file.
43 | - The root App component of your application should import the dummy data from the `dummy-data.js` file with `import dummyData from './dummy-data';` and iterate over said data, passing each individual object as a prop to an instance of `PostContainer`.
44 | - Each `PostContainer` component will then pass the array of comments on each post object as a prop to an instance of the `CommentSection` component.
45 | - The `CommentSection` component will receive the array of comments as props and render a `Comment` component with the username of the poster as well as the post's text. Additionally, there should be an input box that allows users to submit a new comment for any post. We'll work on posting new comments tomorrow.
46 | - Be sure to check the `Types` of the data you are passing around as props in the components that will be using props to present data as DOM elements. This should be linked to your `Comment` component that `Comment Section` will render and potentially to your `Post` component that `Post Container` will render.
47 | - You are free to leverage the Bootstrap library for this project for the purposes of theming and styling. I recommend the awesome [reactstrap](https://reactstrap.github.io/) library, which is a library of Bootstrap components that have been implemented using React, so they're really easy to just drop straight into React projects.
48 | - In addition to Bootstrap for theming, you'll want to add your own styles via CSS. To keep things organized, have the CSS file that corresponds with a component live in the same directory as the component file.
49 |
50 | ---
51 |
52 | Your search bar header should look something like this:
53 | 
54 |
55 | ---
56 |
57 | Your post container should look something like this:
58 | 
59 |
60 | ### Stretch Problems (Day I)
61 |
62 | - Implement the ability to comment on a post with the `Add a comment...` input.
63 | - Use the [moment.js](https://momentjs.com/) library dynamically format the timestamp into a human-readable format like how it is being displayed in the screenshot.
64 |
--------------------------------------------------------------------------------
/assets/InstaClone-componentStructure.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bloominstituteoftechnology/React-Insta-Clone/53d8d07cb6b2611f15c07f9f970b8f346c1b8694/assets/InstaClone-componentStructure.jpg
--------------------------------------------------------------------------------
/assets/folder_structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bloominstituteoftechnology/React-Insta-Clone/53d8d07cb6b2611f15c07f9f970b8f346c1b8694/assets/folder_structure.png
--------------------------------------------------------------------------------
/assets/ig_post.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bloominstituteoftechnology/React-Insta-Clone/53d8d07cb6b2611f15c07f9f970b8f346c1b8694/assets/ig_post.png
--------------------------------------------------------------------------------
/assets/ig_search_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bloominstituteoftechnology/React-Insta-Clone/53d8d07cb6b2611f15c07f9f970b8f346c1b8694/assets/ig_search_bar.png
--------------------------------------------------------------------------------
/dummy-data.js:
--------------------------------------------------------------------------------
1 | const dummyData = [
2 | {
3 | id: "a",
4 | username: "philzcoffee",
5 | thumbnailUrl:
6 | "https://tk-assets.lambdaschool.com/ecd33d34-c124-4b75-92d2-e5c52c171ed8_11201517_887808411287357_1307163552_a.jpg",
7 |
8 | imageUrl:
9 | "https://tk-assets.lambdaschool.com/69cf901b-f96d-466e-a745-ff2a01effac9_philz-image.jpg",
10 | likes: 400,
11 | timestamp: "July 17th 2017, 12:42:40 pm",
12 | comments: [
13 | {
14 | id: 1,
15 | username: "philzcoffee",
16 | text:
17 | "We've got more than just delicious coffees to offer at our shops!"
18 | },
19 | {
20 | id: 2,
21 | username: "biancasaurus",
22 | text: "Looks delicious!"
23 | },
24 | {
25 | id: 3,
26 | username: "martinseludo",
27 | text: "Can't wait to try it!"
28 | }
29 | ]
30 | },
31 | {
32 | id: "b",
33 | username: "fortnite",
34 | thumbnailUrl:
35 | "https://tk-assets.lambdaschool.com/ce601fdf-7cb0-4098-83d3-1a1584a72513_30841289_342445456281079_112845064497004544_n.jpg",
36 | imageUrl:
37 | "https://tk-assets.lambdaschool.com/89d13918-b7a2-4b40-9658-f376ea3f6b59_37131538_213683546146400_1083714364399157248_n.jpg",
38 | likes: 4307,
39 | timestamp: "July 15th 2017, 03:12:09 pm",
40 | comments: [
41 | {
42 | id: 1,
43 | username: "twitch",
44 | text: "Epic Street Fighter action here in Las Vegas at #EVO2017!"
45 | },
46 | {
47 | id: 2,
48 | username: "michaelmarzetta",
49 | text: "Omg that match was crazy"
50 | },
51 | {
52 | id: 3,
53 | username: "themexican_leprechaun",
54 | text: "What a setup"
55 | },
56 | {
57 | id: 4,
58 | username: "dennis_futbol",
59 | text: "It that injustice"
60 | },
61 | {
62 | id: 5,
63 | username: "dennis_futbol",
64 | text: "Is"
65 | }
66 | ]
67 | },
68 | {
69 | id: "c",
70 | username: "playhearthstone",
71 | thumbnailUrl:
72 | "https://tk-assets.lambdaschool.com/c432f179-8bd7-4758-959d-d88a21f96bca_37105899_432228420518610_5035444036064772096_n.jpg",
73 | imageUrl:
74 | "https://tk-assets.lambdaschool.com/43bf01f9-319c-469d-8cf5-0120fe1007f1_yosemite.jpg",
75 | likes: 5306,
76 | timestamp: "July 14th 2017, 10:04:08 am",
77 | comments: [
78 | {
79 | id: 1,
80 | username: "playhearthstone",
81 | text: "Love this shot!"
82 | },
83 | {
84 | id: 2,
85 | username: "awaywetravel",
86 | text: "Yosemite is my most favorite place in the universe"
87 | },
88 | {
89 | id: 3,
90 | username: "awesomebt28",
91 | text: "I like how Half Dome looks so old and useless"
92 | }
93 | ]
94 | }
95 | ];
96 |
97 | export default dummyData;
98 |
--------------------------------------------------------------------------------