diff --git a/06-React-Native/.empty b/06-React-Native/.empty deleted file mode 100644 index e69de29b..00000000 diff --git a/06-React-Native/readme.md b/06-React-Native/readme.md new file mode 100644 index 00000000..a71235d6 --- /dev/null +++ b/06-React-Native/readme.md @@ -0,0 +1,12 @@ +# Topic 6 - React Native + + + +### List of Navigators Implemented + + +:black_large_square: **Stack Navigator** +:black_large_square: **Tabs Navigator** +:black_large_square: **Drawer Navigator** + + diff --git a/06-React-Native/rn-training/README.md b/06-React-Native/rn-training/README.md new file mode 100644 index 00000000..1aeb5b07 --- /dev/null +++ b/06-React-Native/rn-training/README.md @@ -0,0 +1,287 @@ +# React Native Training +An introduction to the React Native ecosystem, including reading sources, and a step by step learning process. + +## Objective +This workshop teaches the basics of React Native development. A participant of this course should end with the basic knowledge to be able to develop a mobile application following best practices. +The course is separated in different topics to guide the atendee to learn the basics of React Native, easing the learning curve. + +At the end of this workshop, the atendee should be able to accomplish a final project consisting of a basic application, covering each of the previous topics. + + +## Who Should Attend +The training will start at a low level, and does not require in depth knowledge of the platform in question. Desirable participant profile (basic knowledge): + +- HTML/XML +- CSS (with Flexbox) +- JavaScript +- Reusable components +- ES6 Modules +- React +- Redux + +## Getting Started +Follow this course in a step by step manner. Each topic covers a specific matter of the React Native development process, and its completion is necessary to achieve the basic knowledge to develop the final project. + +### Introduction +[React Native](https://facebook.github.io/react-native/) is a JavaScript platform that lets you build mobile applications. It's based on ReactJS, and it follows the same development principles. + +In the following chapters, you will learn how to install the necessary tools, and how to write and test your own native applications using React Native. + +### Installation + +There are several ways to build and run a React Native application. In this course we will use [Expo](https://expo.io/). Expo allows you to build the entire app without the need to install and configure neither XCode nor Android Studio. + +First, install Expo (assuming you have [Node](https://nodejs.org/en/download/) installed) +``` +npm install -g expo-cli +``` +You can run your application in your own device, or deploy it in an emulator. + +To try the app in your device, download the Explo Client from the corresponding store. + +[Expo Client for Android](https://play.google.com/store/apps/details?id=host.exp.exponent) + +[Expo Client for iOS](https://itunes.apple.com/us/app/expo-client/id982107779?mt=8) + +To test the application in an emulator, you will to install one. + +To test in iOS, you will need the iOS Simulator from XCode (only available for MacOS) + +To test in Android, you will need either [Android Studio](https://developer.android.com/studio/) or [Genymotion](https://www.genymotion.com/fun-zone/). We reccomend Genymotion as it's the simpler and more lightweight option. + +### Practice +Before starting with the different excercises, you will need to use a base, empty application. Inside the `training-playground` directory, there's a freshly created React Native app, auto-generated by the expo CLI, using +``` +expo init training-playground +``` +Go to the `training-playground` directory and install the necessary dependencies. + +``` +cd training-playground +npm install +``` +Now you should be able to run the app by running + +``` +npm start +``` + +Now your application is ready to run either on your device or an emulator. Follow the instructions on the CLI or the browser tab to start to test. +#### Topic 1 - Core components + +1) Instantiate a [View](https://facebook.github.io/react-native/docs/view) component and experiment changing it's size, border, background, etc. +2) Instantiate several View components, with different sizes and see what happens in different devices +3) Create a [ScrollView](https://facebook.github.io/react-native/docs/scrollview) to hold the created Views. Experiment with the `horizontal` prop. Try different heights and devices +4) Add text to the different Views through the [Text](https://facebook.github.io/react-native/docs/text) component. Apply different text sizes, font weights, and experiment with Text nesting. +5) Include an image inside a View with the [Image](https://facebook.github.io/react-native/docs/image) component. Try a local image, and a remote one. +6) Make one of the images take the entire width of the container View. + +#### Topic 2 - Styling and layout +Learn about creating different layouts with [Yoga](https://yogalayout.com/) and check the examples in +the [React Native Documentation](https://facebook.github.io/react-native/docs/style). + + +1) Create a new screen, in it's own separate directory and copy the followign layout. (Use a separate `styles.js` to hold the styles). +

+ +

+ +2) Apply the same border radius to all three boxes. Try to reuse the border radius style. +3) Copy the following layouts by modifying the fixed widths. The boxes should take the entire height or width of the device in each case. +

+ + +

+ +4) Make the first box take 50% of the device height, the second box take the 30%, and the third one the left 20%. +5) Copy the following layout (the white box is centered both vertically and horizontally) +

+ +

+ +6) Make the background color grey for iOS, and green for Android. +7) Create a component to show a single article, like the following wireframe. +

+ +

+ +#### Topic 3 - Handling Events +Learn about how React Native handles [keyboard events](https://facebook.github.io/react-native/docs/handling-text-input) +and [touches](https://facebook.github.io/react-native/docs/handling-touches). + +1) Create a new screen and add a `TextInput`. Each time the value changes, save it in the screen componente state. +2) Add a `TouchableOpacity` component to clear the `TextInput` on touch. +3) Create a custom `AppTextInput` component that represents a text input element. It should take a `type` prop that let's you change the behavior of the input. +The default value for the `type` prop is "text", and it represents a normal text input. The prop could also receive a value of "password". In that case, it should +add the ability to hide/show the content of the input. +4) Take the `TouchableOpacity` instantiated for exercise 2, and wrap it in a new component. This component +should accept a `type` prop with two possible values: "primary" and "secondary". It will also accept a `disabled` prop. +If disabled, the button should not trigger any action. Follow the next design. +

+ +

+ +#### Topic 4 - Navigation +Learn about [React Navigation](https://reactnavigation.org/). Identify the different ways in which navigation is +accomplished in mobile applications. + +1) Install [react-navigation](https://reactnavigation.org/) +2) Create a new screen in it's own separate file. +3) Add a `TabNavigator` to the application. Add two tabs, the first one should render the screen you have been working on, +the second one should render a new one. +4) Change the tab labels. The first one should be 'Forms', the second one 'Other'. Add icons to both tab labels. +5) Create two new screens, called Forms2 and Forms3. Add a `StackNavigator` containing these new screens, and the Forms screen. +6) Add to the Forms screen the button you created for Topic 2 with the text "Next". When clicked, navigate to Forms2. Do the same for Forms, but navigating to Forms3. +7) Add a button to Forms3 with the text "Finish". When clicked, go back to the first Forms screen. + +#### Topic 5 - Networking +Read about how React Native manages HTTP requests [here](https://facebook.github.io/react-native/docs/network). +1) Change the name of the Forms2 screen to "Posts". Consume this endpoint + ```` + https://jsonplaceholder.typicode.com/posts + ```` + to get a list of sample posts. Show a list containing all posts, rendering the title and the body of each one of them. (Analize + the best option to show a scrollable list). +2) Show a spinner while the request is in progress (check what React Native provides for this scenario). +3) Change the name of the Forms3 screen to "Post". When touched on a post of the list, navigate to the "Post" screen + and show that single post. +4) In the "Post" screen, add information about the user that created it. Use the following endpoint to get that information + ```` + https://jsonplaceholder.typicode.com/users + ```` + + +#### Topic 6 - Leveraging Native features +Learn what it is and how to add native capabilities to a React Native applications. Check instructions +for the [automatic linking](https://facebook.github.io/react-native/docs/linking-libraries-ios). + +1) Change the Tab label "Other" to "Camera". Create a new screen, and add both screens in this tab to a Stack + (just like you did for the first tab). +2) Install and link [react-native-camera](https://github.com/react-native-community/react-native-camera) to supoort the picture taking feature. + Inspect what files in the project have changed to better understand the linking process. +3) In the first screen of the "Camera" tab, open the camera and add the ability to take a picture. +4) In the second screen, whenever a picture is taken, show the picture. Add a button to + go back to the camera screen. + +### Final Project (WIP) + +The following is a sample project to put to practice all the topics learned so far. The definitions and functionalities are provided in a close to reality fashion. +You will be provided with a list of features that the sample applications must have, along with a set of wireframes to guide how the app should look like. +To accomplish the desired features, you will need to consume different services to get the data needed to populate the views + +Please, use this repository as a base for your workshop phase. The idea is to fork this project so everyone uses the same folder structure for the workshop. + +Follow the next steps: + +1. Run `git clone https://github.com/van1985/workshop-rn.git` +2. Enter workshop-rn folder: `cd workshop-rn` +3. Enter redux-boilerplate folder: `cd redux-boilerplate` +4. Run `npm install` +5. open an emulator (android or iOS - from android studio, xCode , genymotion) +6. Run `npm start` (and choose 'a' for android or 'i' for iOS emulator) +7. Enjoy + +#### Wireframes + +##### Home + +

+ +

+ +##### Twitter Details + +

+ +

+ +##### Search & Trends + +

+ +

+

+ +

+ +##### Configuration + +

+ +

+ + +#### Stories + +1. As a user, I want to see my twitter timeline. + +2. As a user, I want to see my twitter timele (with infinite scroll). + +3. As a user, I want to see a specific twitter details. + +4. As a user, I want to see my country trends. + +5. As a user, I want to search on twitter to quickly find news and events. + +6. As a user, I want to see all the results for a specific search (with infinite scroll). + +7. As a user, I want to configure what I want to see in my twitter timeline. This configuration must be reflected in the home section. + +8. As a user, I want to use the app in Android & iOS Platform + +#### Some tips... + +* Use flatlist component for develop the different lists. +* Use ActivityIndicator for develop loading component. Make a specific component, so you can reuse it. +* Use propTypes property for typechecking on the props for a component. +* Use the _base.js file to save all colors and attributes that are cross to the application. + +#### Set Up Twitter Server + +1. Open the console +2. Enter inside `server` folder +3. Execute the command `node server` in the console +3. Open the browser and type `localhost:8080` +4. Should see this text on the brower `Twitter API is running...` + +#### Endpoints + +#### GET statuses / home_timeline + +endpoint: /timeline?count=100 + +Returns a collection of the most recent Tweets posted by the authenticating user and the users they follow. + +##### Parameters + +**count (optional)**: Specifies the number of records to retrieve. Must be less than or equal to 200. Defaults to 20. The value of count is best thought of as a limit to the number of tweets to return because suspended or deleted content is removed after the count has been applied. + +#### GET trends/place + +endpoint: /trends?id=23424747 + +Returns the top 50 trending topics for a specific WOEID, if trending information is available for it. + +##### Parameters + +**id (required)**: The Yahoo! Where On Earth ID of the location to return trending information for. Global information is available by using 1 as the WOEID . + +#### GET search/tweets + +endpoint: /search?q=TanBionicaCocaColaFM + +Returns a collection of relevant Tweets matching a specified query.. This search API searches against a sampling of recent Tweets published in the past 7 days. Part of the 'public' set of APIs. + +##### Parameters + +**q (required)**: A UTF-8, URL-encoded search query of 500 characters maximum, including operators. Queries may additionally be limited by complexity. + +#### GET statuses/show/:id + +endpoint: show?id=1011417658833551361 (id_str) + +Returns a single Tweet, specified by the id parameter. The Tweet’s author will also be embedded within the Tweet. + +##### Parameters + +**id** (required): The numerical ID of the desired Tweet. diff --git a/06-React-Native/rn-training/redux-boilerplate/.babelrc b/06-React-Native/rn-training/redux-boilerplate/.babelrc new file mode 100644 index 00000000..2bcd546d --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": ["babel-preset-expo"], + "env": { + "development": { + "plugins": ["transform-react-jsx-source"] + } + } +} diff --git a/06-React-Native/rn-training/redux-boilerplate/.gitignore b/06-React-Native/rn-training/redux-boilerplate/.gitignore new file mode 100644 index 00000000..14a11718 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/.gitignore @@ -0,0 +1,17 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# expo +.expo/ + +# dependencies +/node_modules + +# misc +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/06-React-Native/rn-training/redux-boilerplate/.watchmanconfig b/06-React-Native/rn-training/redux-boilerplate/.watchmanconfig new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/06-React-Native/rn-training/redux-boilerplate/App.js b/06-React-Native/rn-training/redux-boilerplate/App.js new file mode 100644 index 00000000..b7c25798 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/App.js @@ -0,0 +1,23 @@ +import React from 'react'; +import { AppRegistry } from 'react-native'; +import { Provider } from 'react-redux'; +import { createStore, applyMiddleware } from 'redux'; +import thunk from 'redux-thunk'; + +import AppReducer from './app/reducers'; +import { AppNavigator, middleware } from './app/components/appNavigator'; + + +const store = createStore(AppReducer, applyMiddleware(thunk)); + +class App extends React.Component { + render() { + return ( + + + + ); + } +} + +export default App; \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/App.test.js b/06-React-Native/rn-training/redux-boilerplate/App.test.js new file mode 100644 index 00000000..fc6f975e --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/App.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import App from './App'; + +import renderer from 'react-test-renderer'; + +it('renders without crashing', () => { + const rendered = renderer.create().toJSON(); + expect(rendered).toBeTruthy(); +}); diff --git a/06-React-Native/rn-training/redux-boilerplate/README.md b/06-React-Native/rn-training/redux-boilerplate/README.md new file mode 100644 index 00000000..5edcba09 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/README.md @@ -0,0 +1,201 @@ +This project was bootstrapped with [Create React Native App](https://github.com/react-community/create-react-native-app). + +Below you'll find information about performing common tasks. The most recent version of this guide is available [here](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/README.md). + +## Table of Contents + +* [Updating to New Releases](#updating-to-new-releases) +* [Available Scripts](#available-scripts) + * [npm start](#npm-start) + * [npm test](#npm-test) + * [npm run ios](#npm-run-ios) + * [npm run android](#npm-run-android) + * [npm run eject](#npm-run-eject) +* [Writing and Running Tests](#writing-and-running-tests) +* [Environment Variables](#environment-variables) + * [Configuring Packager IP Address](#configuring-packager-ip-address) +* [Customizing App Display Name and Icon](#customizing-app-display-name-and-icon) +* [Sharing and Deployment](#sharing-and-deployment) + * [Publishing to Expo's React Native Community](#publishing-to-expos-react-native-community) + * [Building an Expo "standalone" app](#building-an-expo-standalone-app) + * [Ejecting from Create React Native App](#ejecting-from-create-react-native-app) + * [Build Dependencies (Xcode & Android Studio)](#build-dependencies-xcode-android-studio) + * [Should I Use ExpoKit?](#should-i-use-expokit) +* [Troubleshooting](#troubleshooting) + * [Networking](#networking) + * [iOS Simulator won't open](#ios-simulator-wont-open) + * [QR Code does not scan](#qr-code-does-not-scan) + +## Updating to New Releases + +You should only need to update the global installation of `create-react-native-app` very rarely, ideally never. + +Updating the `react-native-scripts` dependency of your app should be as simple as bumping the version number in `package.json` and reinstalling your project's dependencies. + +Upgrading to a new version of React Native requires updating the `react-native`, `react`, and `expo` package versions, and setting the correct `sdkVersion` in `app.json`. See the [versioning guide](https://github.com/react-community/create-react-native-app/blob/master/VERSIONS.md) for up-to-date information about package version compatibility. + +## Available Scripts + +If Yarn was installed when the project was initialized, then dependencies will have been installed via Yarn, and you should probably use it to run these commands as well. Unlike dependency installation, command running syntax is identical for Yarn and NPM at the time of this writing. + +### `npm start` + +Runs your app in development mode. + +Open it in the [Expo app](https://expo.io) on your phone to view it. It will reload if you save edits to your files, and you will see build errors and logs in the terminal. + +Sometimes you may need to reset or clear the React Native packager's cache. To do so, you can pass the `--reset-cache` flag to the start script: + +``` +npm start --reset-cache +# or +yarn start --reset-cache +``` + +#### `npm test` + +Runs the [jest](https://github.com/facebook/jest) test runner on your tests. + +#### `npm run ios` + +Like `npm start`, but also attempts to open your app in the iOS Simulator if you're on a Mac and have it installed. + +#### `npm run android` + +Like `npm start`, but also attempts to open your app on a connected Android device or emulator. Requires an installation of Android build tools (see [React Native docs](https://facebook.github.io/react-native/docs/getting-started.html) for detailed setup). We also recommend installing Genymotion as your Android emulator. Once you've finished setting up the native build environment, there are two options for making the right copy of `adb` available to Create React Native App: + +##### Using Android Studio's `adb` + +1. Make sure that you can run adb from your terminal. +2. Open Genymotion and navigate to `Settings -> ADB`. Select “Use custom Android SDK tools” and update with your [Android SDK directory](https://stackoverflow.com/questions/25176594/android-sdk-location). + +##### Using Genymotion's `adb` + +1. Find Genymotion’s copy of adb. On macOS for example, this is normally `/Applications/Genymotion.app/Contents/MacOS/tools/`. +2. Add the Genymotion tools directory to your path (instructions for [Mac](http://osxdaily.com/2014/08/14/add-new-path-to-path-command-line/), [Linux](http://www.computerhope.com/issues/ch001647.htm), and [Windows](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/)). +3. Make sure that you can run adb from your terminal. + +#### `npm run eject` + +This will start the process of "ejecting" from Create React Native App's build scripts. You'll be asked a couple of questions about how you'd like to build your project. + +**Warning:** Running eject is a permanent action (aside from whatever version control system you use). An ejected app will require you to have an [Xcode and/or Android Studio environment](https://facebook.github.io/react-native/docs/getting-started.html) set up. + +## Customizing App Display Name and Icon + +You can edit `app.json` to include [configuration keys](https://docs.expo.io/versions/latest/guides/configuration.html) under the `expo` key. + +To change your app's display name, set the `expo.name` key in `app.json` to an appropriate string. + +To set an app icon, set the `expo.icon` key in `app.json` to be either a local path or a URL. It's recommended that you use a 512x512 png file with transparency. + +## Writing and Running Tests + +This project is set up to use [jest](https://facebook.github.io/jest/) for tests. You can configure whatever testing strategy you like, but jest works out of the box. Create test files in directories called `__tests__` or with the `.test` extension to have the files loaded by jest. See the [the template project](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/App.test.js) for an example test. The [jest documentation](https://facebook.github.io/jest/docs/en/getting-started.html) is also a wonderful resource, as is the [React Native testing tutorial](https://facebook.github.io/jest/docs/en/tutorial-react-native.html). + +## Environment Variables + +You can configure some of Create React Native App's behavior using environment variables. + +### Configuring Packager IP Address + +When starting your project, you'll see something like this for your project URL: + +``` +exp://192.168.0.2:19000 +``` + +The "manifest" at that URL tells the Expo app how to retrieve and load your app's JavaScript bundle, so even if you load it in the app via a URL like `exp://localhost:19000`, the Expo client app will still try to retrieve your app at the IP address that the start script provides. + +In some cases, this is less than ideal. This might be the case if you need to run your project inside of a virtual machine and you have to access the packager via a different IP address than the one which prints by default. In order to override the IP address or hostname that is detected by Create React Native App, you can specify your own hostname via the `REACT_NATIVE_PACKAGER_HOSTNAME` environment variable: + +Mac and Linux: + +``` +REACT_NATIVE_PACKAGER_HOSTNAME='my-custom-ip-address-or-hostname' npm start +``` + +Windows: +``` +set REACT_NATIVE_PACKAGER_HOSTNAME='my-custom-ip-address-or-hostname' +npm start +``` + +The above example would cause the development server to listen on `exp://my-custom-ip-address-or-hostname:19000`. + +## Sharing and Deployment + +Create React Native App does a lot of work to make app setup and development simple and straightforward, but it's very difficult to do the same for deploying to Apple's App Store or Google's Play Store without relying on a hosted service. + +### Publishing to Expo's React Native Community + +Expo provides free hosting for the JS-only apps created by CRNA, allowing you to share your app through the Expo client app. This requires registration for an Expo account. + +Install the `exp` command-line tool, and run the publish command: + +``` +$ npm i -g exp +$ exp publish +``` + +### Building an Expo "standalone" app + +You can also use a service like [Expo's standalone builds](https://docs.expo.io/versions/latest/guides/building-standalone-apps.html) if you want to get an IPA/APK for distribution without having to build the native code yourself. + +### Ejecting from Create React Native App + +If you want to build and deploy your app yourself, you'll need to eject from CRNA and use Xcode and Android Studio. + +This is usually as simple as running `npm run eject` in your project, which will walk you through the process. Make sure to install `react-native-cli` and follow the [native code getting started guide for React Native](https://facebook.github.io/react-native/docs/getting-started.html). + +#### Should I Use ExpoKit? + +If you have made use of Expo APIs while working on your project, then those API calls will stop working if you eject to a regular React Native project. If you want to continue using those APIs, you can eject to "React Native + ExpoKit" which will still allow you to build your own native code and continue using the Expo APIs. See the [ejecting guide](https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md) for more details about this option. + +## Troubleshooting + +### Networking + +If you're unable to load your app on your phone due to a network timeout or a refused connection, a good first step is to verify that your phone and computer are on the same network and that they can reach each other. Create React Native App needs access to ports 19000 and 19001 so ensure that your network and firewall settings allow access from your device to your computer on both of these ports. + +Try opening a web browser on your phone and opening the URL that the packager script prints, replacing `exp://` with `http://`. So, for example, if underneath the QR code in your terminal you see: + +``` +exp://192.168.0.1:19000 +``` + +Try opening Safari or Chrome on your phone and loading + +``` +http://192.168.0.1:19000 +``` + +and + +``` +http://192.168.0.1:19001 +``` + +If this works, but you're still unable to load your app by scanning the QR code, please open an issue on the [Create React Native App repository](https://github.com/react-community/create-react-native-app) with details about these steps and any other error messages you may have received. + +If you're not able to load the `http` URL in your phone's web browser, try using the tethering/mobile hotspot feature on your phone (beware of data usage, though), connecting your computer to that WiFi network, and restarting the packager. If you are using a VPN you may need to disable it. + +### iOS Simulator won't open + +If you're on a Mac, there are a few errors that users sometimes see when attempting to `npm run ios`: + +* "non-zero exit code: 107" +* "You may need to install Xcode" but it is already installed +* and others + +There are a few steps you may want to take to troubleshoot these kinds of errors: + +1. Make sure Xcode is installed and open it to accept the license agreement if it prompts you. You can install it from the Mac App Store. +2. Open Xcode's Preferences, the Locations tab, and make sure that the `Command Line Tools` menu option is set to something. Sometimes when the CLI tools are first installed by Homebrew this option is left blank, which can prevent Apple utilities from finding the simulator. Make sure to re-run `npm/yarn run ios` after doing so. +3. If that doesn't work, open the Simulator, and under the app menu select `Reset Contents and Settings...`. After that has finished, quit the Simulator, and re-run `npm/yarn run ios`. + +### QR Code does not scan + +If you're not able to scan the QR code, make sure your phone's camera is focusing correctly, and also make sure that the contrast on the two colors in your terminal is high enough. For example, WebStorm's default themes may [not have enough contrast](https://github.com/react-community/create-react-native-app/issues/49) for terminal QR codes to be scannable with the system barcode scanners that the Expo app uses. + +If this causes problems for you, you may want to try changing your terminal's color theme to have more contrast, or running Create React Native App from a different terminal. You can also manually enter the URL printed by the packager script in the Expo app's search bar to load it manually. diff --git a/06-React-Native/rn-training/redux-boilerplate/app.json b/06-React-Native/rn-training/redux-boilerplate/app.json new file mode 100644 index 00000000..752f6170 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app.json @@ -0,0 +1,5 @@ +{ + "expo": { + "sdkVersion": "27.0.0" + } +} diff --git a/06-React-Native/rn-training/redux-boilerplate/app/actions/index.js b/06-React-Native/rn-training/redux-boilerplate/app/actions/index.js new file mode 100644 index 00000000..74961649 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/actions/index.js @@ -0,0 +1,18 @@ +export const DATA_AVAILABLE = 'DATA_AVAILABLE'; + +//Import the sample data +import Data from '../instructions.json'; + +export function getData(){ + return (dispatch) => { + + //Make API Call + //For this example, I will be using the sample data in the json file + //delay the retrieval [Sample reasons only] + setTimeout(() => { + const data = Data.instructions; + dispatch({type: DATA_AVAILABLE, data:data}); + }, 2000); + + }; +} \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/components/AppNavigator.js b/06-React-Native/rn-training/redux-boilerplate/app/components/AppNavigator.js new file mode 100644 index 00000000..0290bdb8 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/components/AppNavigator.js @@ -0,0 +1,27 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { createStackNavigator } from 'react-navigation'; +import { + reduxifyNavigator, + createReactNavigationReduxMiddleware, +} from 'react-navigation-redux-helpers'; + +import Routes from '../config/routes'; + +const middleware = createReactNavigationReduxMiddleware( + 'root', + state => state.nav +); + +const RootNavigator = createStackNavigator(Routes); + +const AppWithNavigationState = reduxifyNavigator(RootNavigator, 'root'); + +const mapStateToProps = state => ({ + state: state.nav, +}); + +const AppNavigator = connect(mapStateToProps)(AppWithNavigationState); + +export { RootNavigator, AppNavigator, middleware }; \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/components/home/home.js b/06-React-Native/rn-training/redux-boilerplate/app/components/home/home.js new file mode 100644 index 00000000..0db314f5 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/components/home/home.js @@ -0,0 +1,110 @@ +'use strict'; + +import React, { Component } from 'react'; +import { + StyleSheet, + FlatList, + View, + Text, + ActivityIndicator +} from 'react-native'; + +import {bindActionCreators} from 'redux'; +import { connect } from 'react-redux'; + +import * as Actions from '../../actions'; //Import your actions + +class Home extends Component { + constructor(props) { + super(props); + + this.state = { + }; + + this.renderItem = this.renderItem.bind(this); + } + + componentDidMount() { + this.props.getData(); //call our action + } + + render() { + if (this.props.loading) { + return ( + + + + ); + } else { + return ( + + index.toString()}/> + + ); + } + } + + renderItem({item, index}) { + return ( + + + {(parseInt(index) + 1)}{". "}{item.title} + + + {item.description} + + + ) + } +}; + + + +// The function takes data from the app current state, +// and insert/links it into the props of our component. +// This function makes Redux know that this component needs to be passed a piece of the state +function mapStateToProps(state, props) { + return { + loading: state.dataReducer.loading, + data: state.dataReducer.data + } +} + +// Doing this merges our actions into the component’s props, +// while wrapping them in dispatch() so that they immediately dispatch an Action. +// Just by doing this, we will have access to the actions defined in out actions file (action/home.js) +function mapDispatchToProps(dispatch) { + return bindActionCreators(Actions, dispatch); +} + +//Connect everything +export default connect(mapStateToProps, mapDispatchToProps)(Home); + +const styles = StyleSheet.create({ + activityIndicatorContainer:{ + backgroundColor: "#fff", + alignItems: 'center', + justifyContent: 'center', + flex: 1, + }, + + row:{ + borderBottomWidth: 1, + borderColor: "#ccc", + padding: 10 + }, + + title:{ + fontSize: 15, + fontWeight: "600" + }, + + description:{ + marginTop: 5, + fontSize: 14, + } +}); \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/config/routes.js b/06-React-Native/rn-training/redux-boilerplate/app/config/routes.js new file mode 100644 index 00000000..04a6b22a --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/config/routes.js @@ -0,0 +1,8 @@ +import HomeScreen from '../screens/homeScreen' +import CategoriesScreen from '../screens/categoriesScreen' + +const Routes ={ + Home: { screen: HomeScreen }, + Categories: { screen: CategoriesScreen} +}; +export default Routes; \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/instructions.json b/06-React-Native/rn-training/redux-boilerplate/app/instructions.json new file mode 100644 index 00000000..dfc523ff --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/instructions.json @@ -0,0 +1,40 @@ +{ + "instructions": [ + { + "title": "Create React Native Project", + "description": "react-native init ReactReduxBoilerPlate" + }, + { + "title": "Install Dependencies", + "description": "In your project root, run npm install --save react-redux \nnpm install —save redux \nnpm install —save redux-thunk" + }, + { + "title": "Create Folder Structure", + "description": "In your project root create an 'app' folder. In the app folder create an 'actions' folder , a 'reducers' folder and a 'components' folder." + }, + { + "title": "Create your first action", + "description": "The action is a basic function called from the component whenever we want the whole state of the app to be changed. Our action creator is a simple function returning an object (the action itself)with a type attribute expressing what happened with the app.\nIn your actions folder create a js file 'index.js'" + }, + { + "title": "Create your first reducer", + "description": "Reducers are the ones in charge of updating the state of the app. Redux will automatically pass the current state of the app and the action occurred. It’s up to the reducer to realize if it needs to modify the state or not based on the action.type.\nIn your reducers folder create a js file 'index.js'" + }, + { + "title": "Create your component", + "description": "In your components folder create a js file 'home.js'" + }, + { + "title": "Create Store", + "description": "In the app folder, create a js file 'store.js'" + }, + { + "title": "Link it all together", + "description": "Redux needs to inject a store holding the app state into the app. To do so, it requires a ‘Provider’ wrapping the whole app.In the app folder, create a js file 'setup.js'" + }, + { + "title": "Update your main files", + "description": "Update index.ios.js and index.android.js" + } + ] + } \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/reducers/dataReducer.js b/06-React-Native/rn-training/redux-boilerplate/app/reducers/dataReducer.js new file mode 100644 index 00000000..ba8cb97b --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/reducers/dataReducer.js @@ -0,0 +1,15 @@ +import { DATA_AVAILABLE } from "../actions/" //Import the actions types constant we defined in our actions + +let dataState = { data: [], loading:true }; + +const DataReducer = (state = dataState, action) => { + switch (action.type) { + case DATA_AVAILABLE: + state = Object.assign({}, state, { data: action.data, loading:false }); + return state; + default: + return state; + } +}; + +export default DataReducer; \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/reducers/index.js b/06-React-Native/rn-training/redux-boilerplate/app/reducers/index.js new file mode 100644 index 00000000..34cb7016 --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/reducers/index.js @@ -0,0 +1,10 @@ +import { combineReducers } from 'redux'; +import dataReducer from './dataReducer'; +import nav from './navReducer'; + +const AppReducer = combineReducers({ + nav, + dataReducer +}); + +export default AppReducer; \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/reducers/navReducer.js b/06-React-Native/rn-training/redux-boilerplate/app/reducers/navReducer.js new file mode 100644 index 00000000..bf241e1a --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/reducers/navReducer.js @@ -0,0 +1,37 @@ + +import { NavigationActions } from 'react-navigation'; +import { RootNavigator } from '../components/appNavigator'; + +const firstAction = RootNavigator.router.getActionForPathAndParams('Home'); +const tempNavState = RootNavigator.router.getStateForAction(firstAction); +const initialNavState = RootNavigator.router.getStateForAction( + tempNavState +); + +//function NavReducer(state = initialNavState, action) { +const NavReducer = (state = initialNavState, action) => { + let nextState; + switch (action.type) { + case 'Home': + nextState = RootNavigator.router.getStateForAction( + NavigationActions.navigate({ routeName: 'Home' }), + state + ); + break; + case 'Categories': + nextState = RootNavigator.router.getStateForAction( + NavigationActions.navigate({ routeName: 'Categories' }), + state + ); + break; + default: + nextState = RootNavigator.router.getStateForAction(action, state); + break; + } + + // Simply return the original `state` if `nextState` is null or undefined. + return nextState || state; +} + + +export default NavReducer \ No newline at end of file diff --git a/06-React-Native/rn-training/redux-boilerplate/app/screens/HomeScreen.js b/06-React-Native/rn-training/redux-boilerplate/app/screens/HomeScreen.js new file mode 100644 index 00000000..a8be11ce --- /dev/null +++ b/06-React-Native/rn-training/redux-boilerplate/app/screens/HomeScreen.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { StyleSheet, Text, View, Button } from 'react-native'; +import PropTypes from 'prop-types'; +import Home from '../components/home/home' //Import the component file + +const HomeScreen = ({ navigation }) => ( + + + + ); + } +} diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenPosts.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenPosts.js new file mode 100644 index 00000000..4c2bda0c --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenPosts.js @@ -0,0 +1,72 @@ +import React from 'react'; +import {View, ScrollView, ActivityIndicator, TouchableHighlight} from 'react-native'; +import styles from './screenPosts.style.js'; +import SingleArticle from '../components/SingleArticle'; + + +export default class ScreenPosts extends React.Component { + static navigationOptions = { + drawerLabel: 'Posts', + } + + constructor(props) { + super(props); + this.state = { + url: "https://jsonplaceholder.typicode.com/posts", + isLoading: true, + posts: [] + } + } + + componentDidMount() { + return fetch(this.state.url) + .then((response) => response.json()) + .then((responseJSON) => { + + this.setState({ + isLoading: false, + posts: responseJSON + }) + }) + .catch((error) => { + console.log(error); + }); + } + + handlePosts(){ + let postList = this.state.posts; + let list = []; + + postList.forEach(post => { + list.push( + this.props.navigation.navigate('Post', { + title: post.title, + quote: "Matias Simone", + article: post.body, + id: post.id + })} key={post.id}> + + + + + + ) + }); + return list; + } + + render() { + return ( + + + {this.handlePosts()} + + + + ); + } +} diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenShowPicture.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenShowPicture.js new file mode 100644 index 00000000..081c568e --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenShowPicture.js @@ -0,0 +1,22 @@ +import React from 'react'; +import { View, Image, Button } from 'react-native'; + +import styles from './screenShowPicture.style'; + +export default class ScreenShowPicture extends React.Component { + + render() { + const { navigation } = this.props; + const pic = navigation.getParam('pic', false); + + let url = pic.uri; + + return ( + + + + + ) + } + } diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicOne.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicOne.js new file mode 100644 index 00000000..96b58221 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicOne.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { Text, View, ScrollView, Image} from 'react-native'; +import styles from './screenTopicOne.style.js'; + + +export default class ScreenTopicOne extends React.Component { + + render() { + return ( + + + + Java Script ES6 + + + + HTML 5 + + + + CSS 3 + + + + + + + + ); + } +} diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicThree.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicThree.js new file mode 100644 index 00000000..a8503417 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicThree.js @@ -0,0 +1,52 @@ +import React from 'react'; +import { Text, View, ScrollView, TouchableOpacity} from 'react-native'; +import styles from './screenThree.style.js'; +import AppTextInput from '../components/AppTextInput'; +import AppTouchableOpacity from '../components/AppTouchableOpacity'; + + +export default class ScreenTopicThree extends React.Component { + + constructor(props) { + super(props); + + this.state = { + text: "" + }; + } + + writeText = text => { + this.setState({ + text + }) + } + + clearText = () => { + this.refs.del.clearText() + } + + render() { + return ( + + + Ex 1, 2, 3, 4. + + + + + + + + + + + + + + ); + } +} + diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicTwo.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicTwo.js new file mode 100644 index 00000000..5bede0fc --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenTopicTwo.js @@ -0,0 +1,85 @@ +import React from 'react'; +import { Text, View, ScrollView} from 'react-native'; +import styles from './screenTwo.style.js'; +import SingleArticle from '../components/SingleArticle'; + + +export default class ScreenTopicTwo extends React.Component { + render() { + return ( + + + + Ex.1 + + + + + + + + Ex.2 + + + + + + + + Ex.3 + space-between + In a device without others exercises, the prop + (justifyContent: 'space-between') takes the width of the screen. + + [3.1] + + + + + + + + [3.2] + + + + + + + + Ex.4 (flexGrow) + + In a device without others exercises, the prop + (flexGrow: 50/30/20) takes the 50%, 30%, 20% width of the screen respectively. + + + + + + + + Ex.5 (alignSelf) + + + + + + + + Ex.7 + + + + + + + ); + } +} diff --git a/06-React-Native/rn-training/training-playground/src/screens/ScreenTwo.style.js b/06-React-Native/rn-training/training-playground/src/screens/ScreenTwo.style.js new file mode 100644 index 00000000..e251dab0 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/ScreenTwo.style.js @@ -0,0 +1,120 @@ +import { StyleSheet, Platform } from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + flexDirection: 'column', + ...Platform.select({ + ios: { + backgroundColor: 'grey', + }, + android: { + backgroundColor: 'green', + } + }) + }, + text: { + padding: 5, + fontSize: 50, + color: '#FF1654', + fontWeight: 'bold', + justifyContent: 'center', + alignItems: 'center' + }, + smallText: { + padding: 5, + fontSize: 15, + color: 'black', + fontWeight: 'bold', + justifyContent: 'center', + alignItems: 'center' + }, + + exerciseContainer: { + flex: 1, + alignContent: 'flex-start', + }, + exerciseContainerBetweenRow: { + flexDirection: 'row', + flex: 1, + alignContent: 'flex-start', + justifyContent: 'space-between', + alignItems: 'flex-start' + }, + exerciseContainerBetweenColumn: { + flexDirection: 'column', + flex: 1, + alignContent: 'flex-start', + justifyContent: 'space-between', + alignItems: 'flex-start' + }, + exerciseContainerSmall: { + flex: 1, + width: 500, + height: 500 + }, + + smallBox: { + flex: 1, + width: 50, + height: 50, + margin: 10 + }, + mediumBox: { + flex: 1, + width: 100, + height: 100, + margin: 10 + }, + bigBox: { + flex: 1, + width: 200, + height: 200, + margin: 10 + }, + xsmallBox: { + width: 25, + height: 25, + margin: 10 + }, + box50: { + flex: 1, + width: 50, + flexGrow: 50 + }, + box30: { + flex: 1, + width: 50, + flexGrow: 30 + }, + box20: { + flex: 1, + width: 50, + flexGrow: 20 + }, + boxSelfStart: { + alignSelf: 'flex-start' + }, + boxSelfCenter: { + alignSelf: 'center' + }, + boxSelfEnd: { + alignSelf: 'flex-end' + }, + + colorRedOrange: { + backgroundColor: '#F44336' + }, + colorDarkPurple: { + backgroundColor: '#673AB7' + }, + colorWrite: { + backgroundColor: '#FFFFFF' + }, + + borderRadius: { + borderRadius: 10 + } + }); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenCamera.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenCamera.style.js new file mode 100644 index 00000000..38f6f360 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenCamera.style.js @@ -0,0 +1,24 @@ +import { StyleSheet} from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + }, + cameraView: { + flex: 1, + backgroundColor: 'transparent', + flexDirection: 'row' + }, + buttomFlip: { + flex: 0.1, + alignSelf: 'flex-end', + alignItems: 'center' + }, + buttonText: { + fontSize: 18, + marginBottom: 10, + color: 'white' + } +}); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenOnePost.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenOnePost.style.js new file mode 100644 index 00000000..0532ac62 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenOnePost.style.js @@ -0,0 +1,32 @@ +import { StyleSheet, Platform } from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + flexDirection: 'column', + ...Platform.select({ + ios: { + backgroundColor: 'grey', + }, + android: { + backgroundColor: '#E6E5E6', + } + }) + }, + centerOfTheScreenRow: { + flex: 1, + flexDirection: "row", + alignSelf: "center", + padding: 30 + }, + button: { + flex: 1, + flexDirection: "column", + justifyContent: "flex-end", + alignSelf: "flex-end", + alignItems: "flex-end" + } + + }); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenPosts.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenPosts.style.js new file mode 100644 index 00000000..f3f524e5 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenPosts.style.js @@ -0,0 +1,24 @@ +import { StyleSheet, Platform } from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + flexDirection: 'column', + ...Platform.select({ + ios: { + backgroundColor: 'grey', + }, + android: { + backgroundColor: '#E6E5E6', + } + }) + }, + centerOfTheScreenRow: { + flex: 1, + flexDirection: "row", + alignSelf: "center", + padding: 30 + } + }); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenShowPicture.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenShowPicture.style.js new file mode 100644 index 00000000..57fd8ad6 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenShowPicture.style.js @@ -0,0 +1,13 @@ +import { StyleSheet, Dimensions} from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + }, + imgNormalize: { + width: Dimensions.get('window').width, + height: Dimensions.get('window').height - 35 + } +}); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenThree.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenThree.style.js new file mode 100644 index 00000000..480e55db --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenThree.style.js @@ -0,0 +1,30 @@ +import { StyleSheet, Platform } from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + flexDirection: 'column', + ...Platform.select({ + ios: { + backgroundColor: 'grey', + }, + android: { + backgroundColor: '#E6E5E6', + } + }) + }, + text: { + padding: 5, + fontSize: 50, + color: '#FF1654', + fontWeight: 'bold', + justifyContent: 'center', + alignItems: 'center' + }, + exerciseContainer: { + flex: 1, + alignContent: 'flex-start', + } +}); + \ No newline at end of file diff --git a/06-React-Native/rn-training/training-playground/src/screens/screenTopicOne.style.js b/06-React-Native/rn-training/training-playground/src/screens/screenTopicOne.style.js new file mode 100644 index 00000000..97f01411 --- /dev/null +++ b/06-React-Native/rn-training/training-playground/src/screens/screenTopicOne.style.js @@ -0,0 +1,37 @@ +import { StyleSheet } from 'react-native'; + +export default StyleSheet.create({ + + container: { + flex: 1, + flexDirection: 'column', + justifyContent: 'center', + backgroundColor: '#247BA0' + }, + box: { + width: 100, + height: 100, + backgroundColor: '#70C1B3', + justifyContent: 'center', + marginBottom: 10, + borderRadius: 10 + }, + scroll: { + justifyContent: 'center', + alignItems: 'center' + }, + text: { + color: '#FF1654', + fontWeight: 'bold', + }, + boxImgFlex: { + flex: 1 + }, + boxImgUpload: { + width: 100, + height: 100, + justifyContent: 'center', + alignItems: 'center' + } + }); + \ No newline at end of file diff --git a/06-React-Native/rn-training/wireframes/.DS_Store b/06-React-Native/rn-training/wireframes/.DS_Store new file mode 100644 index 00000000..28c0eb30 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/.DS_Store differ diff --git a/06-React-Native/rn-training/wireframes/configuration.png b/06-React-Native/rn-training/wireframes/configuration.png new file mode 100644 index 00000000..ab4c9411 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/configuration.png differ diff --git a/06-React-Native/rn-training/wireframes/home.png b/06-React-Native/rn-training/wireframes/home.png new file mode 100644 index 00000000..79f9b5b3 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/home.png differ diff --git a/06-React-Native/rn-training/wireframes/search_1.png b/06-React-Native/rn-training/wireframes/search_1.png new file mode 100644 index 00000000..23b9b7bb Binary files /dev/null and b/06-React-Native/rn-training/wireframes/search_1.png differ diff --git a/06-React-Native/rn-training/wireframes/search_2.png b/06-React-Native/rn-training/wireframes/search_2.png new file mode 100644 index 00000000..3d26f405 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/search_2.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/.DS_Store b/06-React-Native/rn-training/wireframes/topic1/.DS_Store new file mode 100644 index 00000000..8bec9dde Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/.DS_Store differ diff --git a/06-React-Native/rn-training/wireframes/topic1/article.png b/06-React-Native/rn-training/wireframes/topic1/article.png new file mode 100644 index 00000000..f9e76a19 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/article.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/boxes.png b/06-React-Native/rn-training/wireframes/topic1/boxes.png new file mode 100644 index 00000000..57aae704 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/boxes.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/boxes2.png b/06-React-Native/rn-training/wireframes/topic1/boxes2.png new file mode 100644 index 00000000..d9329e5f Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/boxes2.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/boxes3.png b/06-React-Native/rn-training/wireframes/topic1/boxes3.png new file mode 100644 index 00000000..2d78df74 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/boxes3.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/boxes4.png b/06-React-Native/rn-training/wireframes/topic1/boxes4.png new file mode 100644 index 00000000..f67d59e7 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/boxes4.png differ diff --git a/06-React-Native/rn-training/wireframes/topic1/ui-button.png b/06-React-Native/rn-training/wireframes/topic1/ui-button.png new file mode 100644 index 00000000..cdb14512 Binary files /dev/null and b/06-React-Native/rn-training/wireframes/topic1/ui-button.png differ diff --git a/06-React-Native/rn-training/wireframes/tweet_details.png b/06-React-Native/rn-training/wireframes/tweet_details.png new file mode 100644 index 00000000..9659ddec Binary files /dev/null and b/06-React-Native/rn-training/wireframes/tweet_details.png differ