Giter Site home page Giter Site logo

kodflix's People

Contributors

kainyryu avatar

Watchers

 avatar  avatar  avatar

kodflix's Issues

Add synopsis & cover to the details page of each TV show

https://github.com/rmallols/kodflix/issues/16

We're already displaying the TV show title on the details page of each TV show.

Let's add now the synopsis and the cover. It's also a good opportunity to keep improving our UI, so please play around with background & font colors, gutters, etc

E.g.
image

Bonus: Please look after the mobile layout!
image

https://kodiri.com/platform/videos/kodflix/5c2fa7f91f00fb0ef12a2bb4

Technical guidance:

  1. Add a synopsis attribute to each entry on the list of shows. Fill them with some relevant info.

  2. Display the synopsis (left) and image (right) on the Details component, following flexbox guidelines:
    https://css-tricks.com/snippets/css/a-guide-to-flexbox/

  3. Re-arrange the layout for mobile, using media queries e.g. by simply switching from display: flex to display: block
    https://www.w3schools.com/Css/css_rwd_mediaqueries.asp
    You can also add some gutters:
    https://www.w3schools.com/cssref/pr_padding.asp

  4. On the main CSS file (App.css) set a generic font and background colour for the root body tag
    https://www.w3schools.com/cssref/pr_text_color.asp
    https://www.w3schools.com/cssref/pr_text_color.asp

Improve the gallery layout

At the moment, our gallery layout comes at 2 flavours:

desktop: 3 covers per row
mobile: 1 cover per row
That's fine, however users with large screens (e.g. UHD, 4K) are telling us cover look too large, so they'd like to have elements sharing the same container

https://kodiri.com/platform/videos/kodflix/5c23d644fb815c3bd5592389

Hint: Simplify the layout by keeping all the covers on a single row. Then, play around with the flex-wrap and flex-basis attributes
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

BONUS: We don't necessarily expect to end up having the same size for every cover. This is a limitation of the CSS flex model, which can be handled with the very new grid system:
https://medium.com/samsung-internet-dev/common-responsive-layouts-with-css-grid-and-some-without-245a862f48df

https://github.com/rmallols/kodflix/issues/11

Run frontend and backend servers in parallel

https://github.com/rmallols/kodflix/issues/21

We still need two commands to startup frontend and backend servers:

  • frontend: npm start.
  • backend: npm start-backend.

We want to start both servers using a single command using npm.

Technical guidance:

  1. At the moment, both servers are running on the same URL (on port 3000). We have to change one of the ports as we cannot have multiple servers running on the same port at the same time. Hence, replace the port on app.js, from 3000 to 3001.

  2. Install npm-run-all. Note the changes on package.json

  3. Create a new task start-all on package.json to run both npm tasks in parallel: npm-run-all -p <task1> <task2>.

...
"scripts": {
    ...
    "start-all": "npm-run-all..."
    ...
"}"
...
  1. Prove both servers work:
  • http://localhost:3000 -> We get the frontend server, with the TV show covers
  • http://localhost:3001 -> We get the backend server, with the TV show data

Please note, at this stage both servers are still disconnected. That means, data is not coming to the frontend from the backend. But that's fine, will connect both servers shortly.

Improve setup of backend server

https://github.com/rmallols/kodflix/issues/20

Up until now, the setup of the backend server has two main issues:

  1. Changes aren't 'hot-reloaded'. That means, every time we introduce a change on the backend code, we are forced to restart the server.

  2. We have to manually type a very long, error prone command to start up the server (node src/backend/...

Please introduce the necessary changes to get rid / minimise these issues, in order to get our productivity improved.

Technical guidance:

  1. To bring hot reloading to our backend JavaScript, we have to install a tool like nodemon. Then, by replacing node with nodemon on the startup command, we'll get our changes automatically reloaded by refreshing the browser, so we won't have to restart the server every time.

  2. All our commands should be based on npm, which quickly became the industry standard. How to run scripts with npm. So just create a new script on package.json called start-backend, and assign the command we've been manually typing to start the backend server.
    Hence, from now on, to start the backend server, we'll just have to run npm run start-backend.

Replace the TV show frontend data source, with the backend one

https://github.com/rmallols/kodflix/issues/24

We are ready to fully replace the TV show data source, from the frontend to the backend. This will notably facilitate future tasks, like e.g. database integration.

Please apply the necessary changes on both the Gallery and Details components.

Technical guidance:

1. Introduce state on the Gallery component, like we did on #13. Save the array of shows we were already retrieving from the backend. Update the loop on the render method to display the shows from the new state, rather than from the external getShows module.

2. With these changes, we haven't solved the problem of displaying the TV cover yet. Historically speaking, we literally imported them on the frontend (e.g. import breakingBad from './cover/images/breaking-bad. This created a big (huge!) string with the image content. As we are now delivering the content from the backend, we shouldn't do that any more. Data fetched from the backend should be simple & easy to manage. Hence, from now on on the Cover component we'll figure out the image resource based on its id:

<img src={require(`<path-to-image>`)} alt='' />

The path will be dynamic, based on the image id. But we can easily solve this problem by using the new and shiny template interpolation mechanism

If an image doesn't load, please ensure the name of the image file matches its corresponding id.

3. Time to follow the very same principle on the Details component (remember, when we click on any cover). Let's recap how the logic worked here:

  • If the TV show was found (based on its id), then display the show details
  • If not, then redirect to a not-found page.

This is still valid, but there's a subtle (but very important) thing to note. Now the data will arrive from the backend, asynchronously. This is a very important principle in the JavaScript world. (Almost) nothing is 'immediate', it may take a while to be available (imagine you're checking the app on the phone, with poor broadband speed. Because of that, by definition TV shows will never be immediately available, so we'd always redirect to the not-found page. To amend that, the logic should look like:

  • If the TV show exists:
    • If it's empty (that means, it doesn't have any property on it yet), we can assume the request to the backend is still in progress -> Do nothing here, just show an empty div. We'll see shortly how to handle loading situations accordingly.
    • If it's been filled (that means, the backend already facilitated its details), then display the show details.
  • If not, then redirect to a not-found page.

4. Prove everything still works as expected. If so, just delete the list of shows we originally set on the frontend (#12)

Bonus:
The images are being accessed from multiple components (Cover and Details, but you can imagine the list will probably grow). Hence, it'd be great to refactor the folder structure a bit.

Please create a new src/frontend/common/images folder, and obviously ensure the path to the images on Cover and Details is correctly amended.

Deploy kodflix to production!

https://github.com/rmallols/kodflix/issues/17

Historically speaking, all the feedback we've received came from our internal / beta customers.

They're quite happy with the current state of the art, so now it's time to make kodflix publicly available!

That would imply we'll have a public URL access, so everybody around the world could check it.

https://kodiri.com/platform/videos/kodflix/5c2fac094f8a290eb464a545

Technical guidance:

We'll deploy our applications to the cloud using Heroku
https://www.heroku.com

It's a very popular framework, with really nice docs and extensive community support.

On top of that, it's free for personal projects, with some limitations (e.g. apps tend to 'sleep', which means first time you access it after a period of inactivity, it'll take few seconds to respond).

Setup process will just take few minutes.

  1. Sign up on Heroku: https://signup.heroku.com/
  2. Follow the getting started guide until the Deploy the app step: https://devcenter.heroku.com/articles/getting-started-with-nodejs
    Please ignore the Prepare the app step - your app is already prepared indeed :).

Hint: On the last step (Deploy the app) we'll create our app into the cloud. The default command the guide suggests is heroku create. As per described, it will create our app with a random name so we'd suggest to set an appropriate name straight away, e.g. heroku create your-app-name

Also note you cannot use kodflix (heroku create kodflix) as an app name since it's been already taken (by me :)) so feel free to use any personal naming conventions you feel comfortable with, e.g. heroku create kodflix-yourName

From now on, you can decide where to push your changes:

  • git push origin master -> changes will be persisted on your GitHub account
  • git push heroku master -> changes will be published
    You can trigger both commands from Visual Studio (... -> Push To...)

The sample app has been already deployed:
https://kodflix.herokuapp.com/

Introduce routing / navigation

Depends on #9

We want to allow users clicking on each cover to navigating to the details page.

The goal here is to prove we can change the URL address by clicking on each cover.

URLs must be unique, but the targeted content will be the same (for now).

So,

Original url address: http://localhost:3000/
New url address (when clicking on any cover): http://localhost:3000/details
Content of the new url address: Hello, this will be the details page for each Movie & TV show :)
image
image

https://kodiri.com/platform/videos/5c1add26d0f7e90e08832429/play

Technical guidance:

How to manage routing with React:

https://facebook.github.io/create-react-app/docs/adding-a-router
https://reacttraining.com/react-router/web/example/basic

Hint: Create a new component (Details) to host the content of the new url address

https://github.com/rmallols/kodflix/issues/8

Introduce a back-end server

https://github.com/rmallols/kodflix/issues/18

Up until now, the npm start we've running on a daily basis managed to start up what we called the 'frontend server', which has been useful to provide browser-oriented content (JavaScript, HTML, CSS, images, etc).

Now, we'd like to start talking about the 'backend server'. That means, running JavaScript 'behind a wall' via Node.js to:

  • Enable security (stuff running in the browser is not safe enough!)
  • Allow integration with third party components (e.g. to saving our list of shows in a database).

The full setup of the backend server will take few steps. For now, let's start simple.

  1. Let's create a logic folder structure. Move all the files and folder inside the src folder (except index.js and index.css) to a new src/frontend folder. Please note you may have to amend some module imports on index.js to match with the new folder layout.

  2. Prove everything still works as expected.

  3. Install Express.js: npm install express --save. Note the changes on package.json

  4. Create a new folder, src/backend. Add a new file on it, app.js. It will be our entry point for the backend JavaScript from now on.

  5. Set app.js with the 'hello world' example provided by Express:
    https://expressjs.com/en/starter/hello-world.html

  6. Stop the frontend server (e.g. pressing ctrl+c) and start the backend one running: node src/backend/app.js

  7. Refresh the browser and check you get a Hello world message:
    image

Keep a unique details URL for each TV show

At the moment, the details page for every TV show share the same URL (http://localhost:3000/details)

This makes impossible to distinguish across multiple shows (how will we know which content is expected to be shown?).

Based on that, now it's time to set unique URLs for each show by:

Set and id (alongside the existing title and image
Redirect to http://localhost:3000/ when user clicks on the cover
image
image

https://kodiri.com/platform/videos/kodflix/5c23d62cfb815c3bd5592388

https://github.com/rmallols/kodflix/issues/10

Enable the backend server in prod

https://github.com/rmallols/kodflix/issues/23

Push the recent changes to prod: git push heroku master.

It doesn't work!
image

Running two Node.js servers in parallel is fine locally, but it's not allowed on Heroku. In other words, we have to merge them into a single server (with a single port).

Technically speaking, we want to achieve this approach:

  • Local development: keep both servers running in parallel (frontend + backend), so we can still take advantage of their individual benefits (e.g. hot reloading in both sides).
  • Production: merge both servers.

Technical guidance:

1. Local development server(s)
We got that already on #22. For readability reasons, let's just rename start with start-frontend and start-all with start-dev.
In other words, we'll start our dev server (frontend + backend) by running npm run start-dev

image
Local servers running locally

2. Production development server
Before going into details, it's important to note up until now create-react-app has been building our production bundles for us, by running the npm run build command internally.
This command creates a new folder called build (more about this below).

As we can use just a single server, we'll use the backend one. We essentially need a couple of changes on app.js

  • Serve files from the build folder: app.use(express.static(path.join(__dirname, '<path-to-build-folder>')));
  • Route the index.html file (the entry point of our app) on the build folder by default:
app.get('*', function (req, res) {
    res.sendFile(path.join(__dirname, '<path-to-build-folder>', 'index.html'));
});

More about routing with Node.js and Express
NOTE: At the moment, our backend port is set to 3001. Heroku doesn't allow to set static ports, so we have to inherit it from its settings: const port = process.env.PORT || 3001;

Finally, we have to fine tune the start task, which is automatically triggered by heroku every time we deploy new stuff with git push heroku master. Using the npm-run-all command, we have to:

  1. Build everything (that means, populate a build folder with all the prod assets.
  2. Start the backend server.

image
Merged servers running in production (note we can use https, which prevents from some errors being shown!)

Show the TV show title on the details page

So it's time to start adding content to the details page of each TV show.

Let's, for the time being, add the title. E.g.

image

We advise to:

  1. Get the list of TV shows from the Details component. Note we already did that on the Gallery one to display the list of covers
  2. Save the Id of the current TV show. URL params can be found under this.props.match.params.<name_of_routing_param>
    More about React props
    https://facebook.github.io/react-native/docs/props.html
  3. Find the TV show matching the saved Id above
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
  4. Display the title of the matched TV show

https://kodiri.com/platform/videos/kodflix/5c2fa7b61f00fb0ef12a2bb2

Hint:
Handling URL Parameters with React Router V4

https://github.com/rmallols/kodflix/issues/14

Componentize the TV show element

The new overlay introduced in #5 is great, users like it.

The mechanism, however, doesn't scale well, as we need to copy&paste it for each TV cover.

Transform the TV show element into a single component, and move it to a new file for scalability purposes.

https://kodiri.com/platform/videos/kodflix/5c1ad64901df830e144d976a

https://github.com/rmallols/kodflix/issues/7

Hint: Managing components with React:

https://reactjs.org/docs/react-component.html
https://reactjs.org/docs/components-and-props.html#composing-components
https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#importing-a-component

Connect the frontend and backend servers

https://github.com/rmallols/kodflix/issues/22

Right, both frontend and backend servers are running in parallel (thanks to the start-all npm task), but they are still disconnected from each other. Let's integrate them!

Please prove we can retrieve the list of TV shows on the frontend from the backend.

Technical guidance:

  1. Due to security reasons, to enable requests from a given url to a different one (in our case, http://localhost:3000 -> http://localhost:3001). We can do that by enabling a proxy from the frontend to the backend.
//Add this as a root prop of your package.json
 "proxy": "http://localhost:3001"
  1. Restart the server and call /rest/shows from the frontend using fetch.

  2. You can then display the list of tv shows on the network tab. You can also display them in the devTools console, using console.log.

image

Move the covers data model to a proper front-end data source

We're hosting the following info about each TV show:

id
title
cover image
We're hosting these details directly on the HTML markup. This approach has some problems:

Data is hard to find, filter, etc
We cannot reuse data easily (e.g. we'd like to show the TV show title again on the /details view
JavaScript comes with a bunch of data structures to getting rid of these problems.
E.g.

Objects: https://www.w3schools.com/Js/js_objects.asp
Arrays: https://www.w3schools.com/js/js_arrays.asp
So the steps here are:

Create an array of objects to handle the TV show details
Iterate over it
For each item, display the corresponding cover
https://kodiri.com/platform/videos/kodflix/5c23dd525fcf740e981b3e39

Hint: Create a new module (a JavaScript file) to host the gallery items (e.g. gallery-get.js) and import it from the gallery component
How to export / import modules in JavaScript
https://medium.com/craft-academy/es6-modules-imports-and-exports-1e5b552ddca9

Hint: how to use the map function on arrays:
https://www.w3schools.com/jsref/jsref_map.asp

https://stackoverflow.com/questions/38282997/rendering-an-array-map-in-react
https://thinkster.io/tutorials/iterating-and-rendering-loops-in-react (scroll down for the tutorial)

rmallols/kodflix#12

Return a list of shows from the backend

https://github.com/rmallols/kodflix/issues/19

We want to keep progressively moving the data logic (for security and accessibility reasons) from the frontend to the backend.

Change the logic on the backend side to return the list of TV shows with the following info:

  • id
  • title
  • synopsis

We'll ignore the image cover for the time being, as requires some rethinking.

Technical guidance:

  1. Create a new file, with the list of shows. Please note, in the backend side, we cannot user the import / export pattern, since it hasn't been fully implemented by Node.js yet.
    For the time being, we have to use its equivalent exports / require pattern (formally known as commonJs
    http://openmymind.net/2012/2/3/Node-Require-and-Exports/

  2. Replace the current root path in app.js, from app.get('/...' to a more convenient architecture, based on rest: app.get('/rest/shows'...

  3. When http://localhost:3000/rest/shows is requested, it should return the list of TV shows
    image
    Rest requests will be properly inspected from the browser devTools. In Chrome, we can find it on:
    Tools -> More Tools -> Developer Tools -> Network tab
    image

Introduce component state

The state is a core concept in React. Its main purpose is to update the UI immediately as soon as soon as the data model changes:
https://www.tutorialspoint.com/reactjs/reactjs_state.htm

Live demo:
https://jsfiddle.net/67675ag9

Let's initialise the state for the Details component (loaded when a TV show is clicked, on localhost:3000/details. Following the links above:

create a new state property called message with the original text we've displayed up until now (Hello, this will be the details page for each Movie & TV show :)
Display the message on the screen
After 3 seconds, update the message to Coming soon! :)
https://kodiri.com/platform/videos/kodflix/5c23dd6a5fcf740e981b3e3a

Hint: use the setTimeout function to change the message after 3 seconds:
https://www.w3schools.com/Jsref/met_win_settimeout.asp

Hint: use arrow functions, when possible
https://codeburst.io/javascript-arrow-functions-for-beginners-926947fc0cdc

https://github.com/rmallols/kodflix/issues/13

Redirect to a "not-found" page when the targeted show doesn't exist

https://github.com/rmallols/kodflix/issues/15

Sometimes, users try to access to the TV show by changing the URL manually.

That's what they get when they do it correctly:
image

That's what they get when they type something wrong in there:
image

That's not great! we should redirect them to a kind of 'not-found' page whenever we don't know the show they're trying to access

image

https://kodiri.com/platform/videos/kodflix/5c2fa7c31f00fb0ef12a2bb3

Technical guidance:

  1. Create a new NotFound component, and return an error message (e.g. Ooops, it looks like this page doesn't exist :()
    BONUS: As this a very basic component, it may be a good opportunity to start using functional components for simplicity reasons
    https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc

  2. Create a new /not-found route on App.js
    Please use <switch> to ensuring no other routers are matched
    https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Switch.md

  3. Ensure you can access the new route (http://localhost:3000/not-found) while the TV show links still work (e.g. http://localhost:3000/breaking-bad)

  4. On the Details components, if we cannot retrieve the corresponding TV show, then redirect to the /not-found page using the Redirect component
    https://www.w3schools.com/js/js_if_else.asp
    https://tylermcginnis.com/react-router-programmatically-navigate/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.