├── .gitignore ├── README.md ├── euroBet ├── App.js ├── README.md ├── app.json ├── assets │ ├── Prostokąt 11@2X.png │ ├── arrow-left.png │ ├── background.png │ ├── belgium.png │ ├── board.png │ ├── bookmark-active.png │ ├── bookmark-white.png │ ├── bookmark.png │ ├── cards.png │ ├── croatia.png │ ├── croatiax3.png │ ├── england-real.png │ ├── england.png │ ├── englandx3.png │ ├── flag.png │ ├── fonts │ │ ├── Montserrat-Bold.otf │ │ ├── Montserrat-Regular.otf │ │ └── montserrat.zip │ ├── fouls.png │ ├── france.png │ ├── gear-active.png │ ├── gear.png │ ├── germany.png │ ├── hungary.png │ ├── iceland.png │ ├── icon.png │ ├── ireland.png │ ├── italy.png │ ├── logo.png │ ├── matches-active.png │ ├── matches.png │ ├── photo.png │ ├── poland.png │ ├── polandx3.png │ ├── portugal.png │ ├── portugalx3.png │ ├── profile-active.png │ ├── profile.png │ ├── red-card.png │ ├── search.png │ ├── shots-off.png │ ├── shots-target.png │ ├── slovakia.png │ ├── small-ball.png │ ├── spain.png │ ├── splash.png │ ├── substitution.png │ ├── switzerland.png │ ├── switzerlandx3.png │ ├── triangle-right.png │ ├── triangle.png │ ├── wales.png │ ├── walesx3.png │ └── yellow-card.png ├── babel.config.js ├── components │ ├── Block.js │ ├── SectionWithCards.js │ ├── Text.js │ └── index.js ├── mock.js ├── package.json ├── screen │ ├── Login │ │ └── index.js │ ├── Matches │ │ └── index.js │ ├── Overview │ │ └── index.js │ ├── Top │ │ └── index.js │ ├── UnderConstruction.js │ └── navigate.js ├── theme.js └── yarn.lock ├── heyU ├── App.js ├── README.md ├── app.json ├── assets │ ├── black-info.png │ ├── delete.png │ ├── emoji.png │ ├── fonts │ │ ├── Lato-Black.ttf │ │ ├── Lato-Bold.ttf │ │ ├── Lato-Regular.ttf │ │ ├── Lato-Semibold.ttf │ │ └── lato.zip │ ├── icon.png │ ├── info.png │ ├── left-arrow.png │ ├── message.png │ ├── more-horizontal.png │ ├── more.png │ ├── plus.png │ ├── power.png │ ├── profile.png │ ├── right-arrow.png │ ├── search-mini.png │ ├── search.png │ ├── send.png │ ├── splash.png │ ├── user1-mini.png │ ├── user1.png │ ├── user1x2.png │ ├── user1x3.png │ ├── user2.png │ ├── user2x2.png │ ├── user2x3.png │ ├── user3.png │ ├── user3x2.png │ ├── user3x3.png │ ├── user4.png │ ├── user4x2.png │ ├── user4x3.png │ ├── user5.png │ ├── user5x2.png │ ├── user5x3.png │ ├── user6.png │ ├── user6x2.png │ ├── user6x3.png │ ├── user7.png │ ├── user7x2.png │ ├── user7x3.png │ ├── user8.png │ ├── user8x2.png │ └── user8x3.png ├── babel.config.js ├── components │ ├── Block.js │ ├── ImageNotify.js │ ├── Text.js │ └── index.js ├── mock.js ├── package.json ├── screen │ ├── Chat │ │ └── index.js │ ├── Contacts │ │ └── index.js │ ├── Groups │ │ └── index.js │ ├── Login │ │ └── index.js │ ├── Messages │ │ └── index.js │ ├── Profile │ │ └── index.js │ ├── UnderConstruction.js │ └── navigate.js ├── theme.js └── yarn.lock ├── luxuryShop ├── App.js ├── README.md ├── app.json ├── assets │ ├── back.png │ ├── c1.jpg │ ├── c2.jpg │ ├── c3.jpg │ ├── cart-white.png │ ├── cart.png │ ├── d1.jpg │ ├── d2.jpg │ ├── d3.jpg │ ├── fonts │ │ ├── Analogue55Regular.ttf │ │ ├── Analogue56Oblique.ttf │ │ ├── Analogue65Medium.ttf │ │ ├── GenBasB.ttf │ │ ├── GenBasR.ttf │ │ ├── Gentium-Basic.zip │ │ └── analogue-12.zip │ ├── h1.jpg │ ├── h2.jpg │ ├── h3.jpg │ ├── h4.jpg │ ├── icon.png │ ├── pink-drop.png │ ├── speech.png │ ├── splash.png │ ├── star-active.png │ ├── star.png │ ├── top-right.png │ └── user.jpg ├── babel.config.js ├── components │ ├── Block.js │ ├── Carrousel.js │ ├── Text.js │ └── index.js ├── package.json ├── screen │ ├── Home │ │ └── index.js │ ├── Product │ │ └── index.js │ └── navigate.js ├── theme.js └── yarn.lock └── triviaAlt ├── App.js ├── README.md ├── app.json ├── assets ├── back.png ├── collapse.png ├── fire-active.png ├── fire.png ├── icon.png ├── light-active.png ├── light.png ├── ranking-active.png ├── ranking.png ├── splash.png ├── star-active.png ├── star.png ├── top-left.png └── top-right.png ├── babel.config.js ├── components ├── Block.js ├── Text.js └── index.js ├── package-lock.json ├── package.json ├── theme.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | */node_modules 2 | *.expo -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RN Front End Adventures 2 | Welcome! 3 | Here I make cool React Native Apps using [Dribbble](https://dribbble.com/) designs 4 | 5 | 6 | | Project | Preview | Screens | Estimation | Status | 7 | | ------ | ------ | :------: | :------: | :------: | 8 | | [HeyU Chat App](https://dribbble.com/shots/3111555-HeyU-Mobile-App-PSD/attachments) | | 6 | ~14 hours | :white_check_mark: | 9 | | :fire: [EuroBet](https://dribbble.com/shots/2809397-Eurobet-Mobile-App-Free-PSD/attachments) :fire: | | 6 | ~8 hours | :white_check_mark: | 10 | | [Luxury Shop](https://dribbble.com/shots/6142872-Luxury-Goods-App/attachments) | | 2 | ~4 hours | :white_check_mark: | 11 | | [Trivia Alternative](https://dribbble.com/shots/6207795-Trivia-App-Alternative/attachments) | | 1 | ~2 hours | :white_check_mark: | 12 | | [Your App Here](https://github.com/dev-andremonteiro/react-native-frontend-adventure/issues/new?assignees=&labels=&template=feature_request.md&title=) | Awesome design | - | ~ hours | :point_left: | 13 | 14 | *Inpired by [Dribbble2React](https://github.com/react-ui-kit/dribbble2react) :heart:* 15 | 16 | 17 | [My Expo Profile](https://expo.io/@menorme) 18 | 19 | 20 | :bird: [Follow me on Twitter](https://twitter.com/DAndremonteiro) :) 21 | -------------------------------------------------------------------------------- /euroBet/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ActivityIndicator, 4 | Image, 5 | ImageBackground, 6 | StatusBar, 7 | } from 'react-native'; 8 | 9 | import { Asset } from 'expo-asset'; 10 | import * as Font from 'expo-font'; 11 | 12 | import { Block } from './components'; 13 | 14 | import Navigator from './screen/navigate'; 15 | 16 | function loadIcons(images) { 17 | return images.map((image) => { 18 | if (typeof image === 'string') { 19 | return Image.prefetch(image); 20 | } else { 21 | return Asset.fromModule(image).downloadAsync(); 22 | } 23 | }); 24 | } 25 | 26 | export default class App extends React.Component { 27 | state = { 28 | iconsLoaded: false, 29 | }; 30 | 31 | async componentDidMount() { 32 | const imageAssets = loadIcons([ 33 | require('./assets/arrow-left.png'), 34 | require('./assets/background.png'), 35 | require('./assets/belgium.png'), 36 | require('./assets/board.png'), 37 | require('./assets/bookmark-active.png'), 38 | require('./assets/bookmark-white.png'), 39 | require('./assets/bookmark.png'), 40 | require('./assets/cards.png'), 41 | require('./assets/croatia.png'), 42 | require('./assets/croatiax3.png'), 43 | require('./assets/england.png'), 44 | require('./assets/england-real.png'), 45 | require('./assets/englandx3.png'), 46 | require('./assets/flag.png'), 47 | require('./assets/fouls.png'), 48 | require('./assets/france.png'), 49 | require('./assets/gear.png'), 50 | require('./assets/gear-active.png'), 51 | require('./assets/germany.png'), 52 | require('./assets/hungary.png'), 53 | require('./assets/iceland.png'), 54 | require('./assets/icon.png'), 55 | require('./assets/ireland.png'), 56 | require('./assets/italy.png'), 57 | require('./assets/logo.png'), 58 | require('./assets/matches-active.png'), 59 | require('./assets/matches.png'), 60 | require('./assets/poland.png'), 61 | require('./assets/polandx3.png'), 62 | require('./assets/portugal.png'), 63 | require('./assets/portugalx3.png'), 64 | require('./assets/profile-active.png'), 65 | require('./assets/profile.png'), 66 | require('./assets/red-card.png'), 67 | require('./assets/search.png'), 68 | require('./assets/shots-off.png'), 69 | require('./assets/shots-target.png'), 70 | require('./assets/slovakia.png'), 71 | require('./assets/triangle.png'), 72 | require('./assets/triangle-right.png'), 73 | require('./assets/small-ball.png'), 74 | require('./assets/spain.png'), 75 | require('./assets/splash.png'), 76 | require('./assets/substitution.png'), 77 | require('./assets/switzerland.png'), 78 | require('./assets/switzerlandx3.png'), 79 | require('./assets/wales.png'), 80 | require('./assets/walesx3.png'), 81 | require('./assets/photo.png'), 82 | require('./assets/yellow-card.png'), 83 | ]); 84 | 85 | await Font.loadAsync({ 86 | 'Monserrat-Regular': require('./assets/fonts/Montserrat-Regular.otf'), 87 | 'Monserrat-Bold': require('./assets/fonts/Montserrat-Bold.otf'), 88 | }); 89 | 90 | await Promise.all([...imageAssets]) 91 | .then(() => this.setState({ iconsLoaded: true })) 92 | .catch((e) => console.log(e)); 93 | } 94 | 95 | render() { 96 | if (!this.state.iconsLoaded) { 97 | return ( 98 | 99 | 100 | 101 | ); 102 | } 103 | return ( 104 | 105 | 106 | 116 | 117 | 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /euroBet/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 | 7 |

8 |

9 | 10 |

11 | 12 | # EuroBet App 13 | 14 | built with [React Native](https://github.com/facebook/react-native) and [Expo](https://github.com/expo/expo). 15 | 16 | ## Installation 17 | 18 | - Clone this repo `git clone https://github.com/dev-andremonteiro/react-native-frontend-adventure.git` 19 | - `cd react-native-frontend-adventure` 20 | - `cd euroBet` 21 | - run `npm install` 22 | - run `expo start` 23 | 24 | ## Design 25 | 26 | Props to Jakub at Team [Spoko](http://spoko.io/) 27 | 28 | - [Dribbble](https://dribbble.com/jakubkowalczyk) 29 | - [Twitter](https://twitter.com/jakubdesign) 30 | - [Behance](https://www.behance.net/jakubkowalczyk) 31 | 32 | Show some :heart: for the designer that made this possible 33 | 34 | ## Help me 35 | 36 | - [ ] I don't know how to implement this imagebackground on all stacks, for some 37 | reason it doesn't pass down to the StackNavigator child from the TabNavigator 38 | parent,thats why I had to use ImageBackground on all screens inside StackNavigator. 39 | 40 | - [ ] I only got images twice the pixel of the PSD so I had to divide all Image 41 | heights and widths of 2. 42 | 43 | ## Developer 44 | 45 | Andre Monteiro [dev-andremonteiro](https://github.com/dev-andremonteiro) 46 | 47 | [Follow me on Twitter](https://twitter.com/DAndremonteiro) :) 48 | -------------------------------------------------------------------------------- /euroBet/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Euro Bet", 4 | "slug": "euro-bet", 5 | "privacy": "public", 6 | "platforms": [ 7 | "ios", 8 | "android" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | }, 27 | "description": "Part of the front end advetures using React Native and Expo", 28 | "githubUrl": "https://github.com/dev-andremonteiro/react-native-frontend-adventure" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /euroBet/assets/Prostokąt 11@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/Prostokąt 11@2X.png -------------------------------------------------------------------------------- /euroBet/assets/arrow-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/arrow-left.png -------------------------------------------------------------------------------- /euroBet/assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/background.png -------------------------------------------------------------------------------- /euroBet/assets/belgium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/belgium.png -------------------------------------------------------------------------------- /euroBet/assets/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/board.png -------------------------------------------------------------------------------- /euroBet/assets/bookmark-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/bookmark-active.png -------------------------------------------------------------------------------- /euroBet/assets/bookmark-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/bookmark-white.png -------------------------------------------------------------------------------- /euroBet/assets/bookmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/bookmark.png -------------------------------------------------------------------------------- /euroBet/assets/cards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/cards.png -------------------------------------------------------------------------------- /euroBet/assets/croatia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/croatia.png -------------------------------------------------------------------------------- /euroBet/assets/croatiax3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/croatiax3.png -------------------------------------------------------------------------------- /euroBet/assets/england-real.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/england-real.png -------------------------------------------------------------------------------- /euroBet/assets/england.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/england.png -------------------------------------------------------------------------------- /euroBet/assets/englandx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/englandx3.png -------------------------------------------------------------------------------- /euroBet/assets/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/flag.png -------------------------------------------------------------------------------- /euroBet/assets/fonts/Montserrat-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/fonts/Montserrat-Bold.otf -------------------------------------------------------------------------------- /euroBet/assets/fonts/Montserrat-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/fonts/Montserrat-Regular.otf -------------------------------------------------------------------------------- /euroBet/assets/fonts/montserrat.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/fonts/montserrat.zip -------------------------------------------------------------------------------- /euroBet/assets/fouls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/fouls.png -------------------------------------------------------------------------------- /euroBet/assets/france.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/france.png -------------------------------------------------------------------------------- /euroBet/assets/gear-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/gear-active.png -------------------------------------------------------------------------------- /euroBet/assets/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/gear.png -------------------------------------------------------------------------------- /euroBet/assets/germany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/germany.png -------------------------------------------------------------------------------- /euroBet/assets/hungary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/hungary.png -------------------------------------------------------------------------------- /euroBet/assets/iceland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/iceland.png -------------------------------------------------------------------------------- /euroBet/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/icon.png -------------------------------------------------------------------------------- /euroBet/assets/ireland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/ireland.png -------------------------------------------------------------------------------- /euroBet/assets/italy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/italy.png -------------------------------------------------------------------------------- /euroBet/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/logo.png -------------------------------------------------------------------------------- /euroBet/assets/matches-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/matches-active.png -------------------------------------------------------------------------------- /euroBet/assets/matches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/matches.png -------------------------------------------------------------------------------- /euroBet/assets/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/photo.png -------------------------------------------------------------------------------- /euroBet/assets/poland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/poland.png -------------------------------------------------------------------------------- /euroBet/assets/polandx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/polandx3.png -------------------------------------------------------------------------------- /euroBet/assets/portugal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/portugal.png -------------------------------------------------------------------------------- /euroBet/assets/portugalx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/portugalx3.png -------------------------------------------------------------------------------- /euroBet/assets/profile-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/profile-active.png -------------------------------------------------------------------------------- /euroBet/assets/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/profile.png -------------------------------------------------------------------------------- /euroBet/assets/red-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/red-card.png -------------------------------------------------------------------------------- /euroBet/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/search.png -------------------------------------------------------------------------------- /euroBet/assets/shots-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/shots-off.png -------------------------------------------------------------------------------- /euroBet/assets/shots-target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/shots-target.png -------------------------------------------------------------------------------- /euroBet/assets/slovakia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/slovakia.png -------------------------------------------------------------------------------- /euroBet/assets/small-ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/small-ball.png -------------------------------------------------------------------------------- /euroBet/assets/spain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/spain.png -------------------------------------------------------------------------------- /euroBet/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/splash.png -------------------------------------------------------------------------------- /euroBet/assets/substitution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/substitution.png -------------------------------------------------------------------------------- /euroBet/assets/switzerland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/switzerland.png -------------------------------------------------------------------------------- /euroBet/assets/switzerlandx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/switzerlandx3.png -------------------------------------------------------------------------------- /euroBet/assets/triangle-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/triangle-right.png -------------------------------------------------------------------------------- /euroBet/assets/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/triangle.png -------------------------------------------------------------------------------- /euroBet/assets/wales.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/wales.png -------------------------------------------------------------------------------- /euroBet/assets/walesx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/walesx3.png -------------------------------------------------------------------------------- /euroBet/assets/yellow-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/euroBet/assets/yellow-card.png -------------------------------------------------------------------------------- /euroBet/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /euroBet/components/Block.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { StyleSheet, View } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Block extends Component { 7 | render() { 8 | const { 9 | flex, 10 | row, 11 | column, 12 | center, 13 | middle, 14 | left, 15 | right, 16 | card, 17 | shadow, 18 | color, 19 | white, 20 | space, 21 | style, 22 | children, 23 | ...props 24 | } = this.props; 25 | 26 | const blockStyles = [ 27 | styles.block, 28 | flex && { flex }, 29 | flex === false && { flex: 0 }, // reset / disable flex 30 | row && styles.row, 31 | column && styles.column, 32 | center && styles.center, 33 | middle && styles.middle, 34 | left && styles.left, 35 | right && styles.right, 36 | card && styles.card, 37 | shadow && styles.shadow, 38 | space && { justifyContent: `space-${space}` }, 39 | white && styles.white, 40 | color && styles[color], // predefined styles colors for backgroundColor 41 | color && !styles[color] && { backgroundColor: color }, // custom backgroundColor 42 | style // rewrite predefined styles 43 | ]; 44 | 45 | return ( 46 | 47 | {children} 48 | 49 | ); 50 | } 51 | } 52 | 53 | const styles = StyleSheet.create({ 54 | block: { 55 | flex: 1 56 | }, 57 | row: { 58 | flexDirection: "row" 59 | }, 60 | column: { 61 | flexDirection: "column" 62 | }, 63 | card: { 64 | borderRadius: theme.sizes.border 65 | }, 66 | center: { 67 | alignItems: "center" 68 | }, 69 | middle: { 70 | justifyContent: "center" 71 | }, 72 | left: { 73 | justifyContent: "flex-start" 74 | }, 75 | right: { 76 | justifyContent: "flex-end" 77 | }, 78 | shadow: { 79 | shadowColor: theme.colors.black, 80 | shadowOffset: { width: 3, height: 3 }, 81 | shadowOpacity: 0.2, 82 | shadowRadius: 10 83 | }, 84 | white: { backgroundColor: theme.colors.white } 85 | }); 86 | -------------------------------------------------------------------------------- /euroBet/components/SectionWithCards.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Block, Text } from "../components"; 4 | 5 | export default class SectionWithCards extends React.Component { 6 | render() { 7 | const { title, inside } = this.props; 8 | const stringOrArray = typeof title === "string"; 9 | 10 | return ( 11 | 12 | 21 | {title && 22 | (stringOrArray ? ( 23 | {title} 24 | ) : ( 25 | title.map((i, n) => {i}) 26 | ))} 27 | 28 | {inside} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /euroBet/components/Text.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Text, StyleSheet } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Typography extends Component { 7 | render() { 8 | const { 9 | title, 10 | h1, 11 | h2, 12 | small, 13 | size, 14 | // styling 15 | bold, 16 | center, 17 | right, 18 | // colors 19 | color, 20 | black, 21 | white, 22 | primary, 23 | secondary, 24 | style, 25 | children, 26 | ...props 27 | } = this.props; 28 | 29 | const textStyles = [ 30 | styles.text, 31 | title && styles.title, 32 | h1 && styles.h1, 33 | h2 && styles.h2, 34 | small && styles.small, 35 | size && { fontSize: size }, 36 | bold && styles.bold, 37 | center && styles.center, 38 | right && styles.right, 39 | color && styles[color], 40 | color && !styles[color] && { color }, 41 | // color shortcuts 42 | primary && styles.primary, 43 | secondary && styles.secondary, 44 | black && styles.black, 45 | white && styles.white, 46 | style // rewrite predefined styles 47 | ]; 48 | 49 | return ( 50 | 51 | {children} 52 | 53 | ); 54 | } 55 | } 56 | 57 | const styles = StyleSheet.create({ 58 | // default style 59 | text: { 60 | fontFamily: "Monserrat-Bold", 61 | fontSize: theme.sizes.font, 62 | color: theme.colors.secondary 63 | }, 64 | // variations 65 | bold: { 66 | fontFamily: "Monserrat-Regular" 67 | }, 68 | // position 69 | center: { textAlign: "center" }, 70 | right: { textAlign: "right" }, 71 | // colors 72 | secondary: { color: theme.colors.secondary }, 73 | primary: { color: theme.colors.primary }, 74 | black: { color: theme.colors.black }, 75 | white: { color: theme.colors.white }, 76 | gray: { color: theme.colors.gray }, 77 | // fonts 78 | title: theme.fonts.title, 79 | h1: theme.fonts.h1, 80 | h2: theme.fonts.h2, 81 | small: theme.fonts.small 82 | }); 83 | -------------------------------------------------------------------------------- /euroBet/components/index.js: -------------------------------------------------------------------------------- 1 | import Block from './Block'; 2 | import Text from './Text'; 3 | 4 | export { Block, Text }; -------------------------------------------------------------------------------- /euroBet/mock.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Image } from "react-native"; 3 | 4 | export const dates = [ 5 | { 6 | date: "29.03.2019", 7 | DOW: "TODAY", 8 | epoch: "Round of 16", 9 | games: [ 10 | { 11 | live: false, 12 | country: "Switzerland", 13 | flag: require("./assets/switzerland.png"), 14 | flagx3: require("./assets/switzerlandx3.png"), 15 | adversary: "Poland", 16 | advFlag: require("./assets/poland.png"), 17 | advFlagx3: require("./assets/polandx3.png"), 18 | result: "0 - 1" 19 | }, 20 | { 21 | live: false, 22 | country: "Wales", 23 | flag: require("./assets/wales.png"), 24 | flagx3: require("./assets/walesx3.png"), 25 | adversary: "N. Ireland", 26 | advFlag: require("./assets/england.png"), 27 | advFlagx3: require("./assets/englandx3.png"), 28 | result: "2 - 0" 29 | }, 30 | { 31 | live: true, 32 | country: "Croatia", 33 | flag: require("./assets/croatia.png"), 34 | flagx3: require("./assets/croatiax3.png"), 35 | adversary: "Portugal", 36 | advFlag: require("./assets/portugal.png"), 37 | advFlagx3: require("./assets/portugalx3.png"), 38 | result: "3 - 3" 39 | } 40 | ] 41 | }, 42 | { 43 | date: "30.03.2019", 44 | DOW: "FRIDAY", 45 | epoch: "Round of 16", 46 | games: [ 47 | { 48 | live: false, 49 | country: "France", 50 | flag: require("./assets/france.png"), 51 | adversary: "Ireland", 52 | advFlag: require("./assets/ireland.png"), 53 | result: "15:00" 54 | }, 55 | { 56 | live: false, 57 | country: "Germany", 58 | flag: require("./assets/germany.png"), 59 | adversary: "Slovakia", 60 | advFlag: require("./assets/slovakia.png"), 61 | result: "18:00" 62 | }, 63 | { 64 | live: false, 65 | country: "Hungary", 66 | flag: require("./assets/hungary.png"), 67 | adversary: "Belgium", 68 | advFlag: require("./assets/belgium.png"), 69 | result: "21:00" 70 | } 71 | ] 72 | }, 73 | { 74 | date: "31.03.2019", 75 | DOW: "SATURDAY", 76 | epoch: "Round of 16", 77 | games: [ 78 | { 79 | live: false, 80 | country: "Italy", 81 | flag: require("./assets/italy.png"), 82 | adversary: "Spain", 83 | advFlag: require("./assets/spain.png"), 84 | result: "15:00" 85 | }, 86 | { 87 | live: false, 88 | country: "England", 89 | flag: require("./assets/england-real.png"), 90 | adversary: "Iceland", 91 | advFlag: require("./assets/iceland.png"), 92 | result: "18:00" 93 | } 94 | ] 95 | } 96 | ]; 97 | 98 | export const liveStream = { 99 | time: "65'", 100 | moments: [ 101 | [ 102 | { 103 | time: "65'", 104 | player: "Ivan Perisic", 105 | type: "yellow", 106 | from: "country" 107 | }, 108 | { 109 | time: "63'", 110 | player: "Mateo Kovacic", 111 | type: "substitution", 112 | out: "Marko Rog" 113 | }, 114 | { 115 | time: "63'", 116 | player: "Cristiano Ronaldo", 117 | type: "goal", 118 | from: "adversary" 119 | }, 120 | { 121 | time: "50'", 122 | player: "Marko Pjaca", 123 | type: "yellow", 124 | from: "country" 125 | }, 126 | { 127 | time: "46'", 128 | player: "Cristiano Ronaldo", 129 | type: "goal", 130 | from: "adversary" 131 | } 132 | ], 133 | [ 134 | { 135 | time: "44'", 136 | player: "Luka Modric", 137 | type: "goal", 138 | from: "country" 139 | }, 140 | { 141 | time: "38'", 142 | player: "Pepe", 143 | type: "yellow", 144 | from: "country" 145 | } 146 | ] 147 | ] 148 | }; 149 | 150 | export const highlights = liveStream.moments.map(item => 151 | item.map(i => { 152 | if (i.type === "goal" || i.type === "yellow" || i.type === "red") return i; 153 | }) 154 | ); 155 | 156 | export const stats = [ 157 | { 158 | title: "Shots on target", 159 | icon: ( 160 | 164 | ), 165 | country: 6, 166 | adversary: 1, 167 | total: 7 168 | }, 169 | { 170 | title: "Shots off target", 171 | icon: ( 172 | 176 | ), 177 | country: 2, 178 | adversary: 2, 179 | total: 4 180 | }, 181 | { 182 | title: "Ball possesion", 183 | icon: ( 184 | 188 | ), 189 | country: 65, 190 | adversary: 35, 191 | total: 100 192 | }, 193 | { 194 | title: "Corners", 195 | icon: ( 196 | 200 | ), 201 | country: 5, 202 | adversary: 1, 203 | total: 6 204 | }, 205 | { 206 | title: "Fouls", 207 | icon: ( 208 | 212 | ), 213 | country: 3, 214 | adversary: 4, 215 | total: 7 216 | }, 217 | { 218 | title: "Yellow Cards", 219 | icon: ( 220 | 224 | ), 225 | country: 1, 226 | adversary: 2, 227 | total: 3 228 | } 229 | ]; 230 | 231 | export const top = [ 232 | { name: "Cristiano Ronaldo", goals: 7 }, 233 | { name: "Álvaro Morata", goals: 6 }, 234 | { name: "Rober Lewandowski", goals: 5 }, 235 | { name: "Dimitri Payet", goals: 5 }, 236 | { name: "Romelu Lukaku", goals: 4 }, 237 | { name: "Nani", goals: 3 }, 238 | { name: "Ivan Perisic", goals: 3 }, 239 | { name: "Luka Mordic", goals: 2 }, 240 | { name: "Nice! You", goals: 2 }, 241 | { name: "saw this! ;)", goals: 1 } 242 | ]; 243 | -------------------------------------------------------------------------------- /euroBet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "eject": "expo eject" 8 | }, 9 | "dependencies": { 10 | "expo": "^40.0.0", 11 | "expo-asset": "~8.2.1", 12 | "expo-font": "~8.4.0", 13 | "expo-linear-gradient": "~8.4.0", 14 | "react": "16.13.1", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz", 16 | "react-native-gesture-handler": "~1.8.0", 17 | "react-native-screens": "~2.15.2", 18 | "react-navigation": "^3.3.2" 19 | }, 20 | "devDependencies": { 21 | "babel-preset-expo": "8.3.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /euroBet/screen/Login/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | Image, 6 | TouchableOpacity 7 | } from "react-native"; 8 | 9 | import { Block, Text } from "../../components"; 10 | import * as theme from "../../theme"; 11 | 12 | class Login extends React.Component { 13 | changeScreen = () => this.props.navigation.navigate("App"); 14 | 15 | render() { 16 | return ( 17 | 18 | 19 | 20 | 24 | 25 | Lorem ipsum dolor sit amet consec 26 | 27 | 28 | 29 | 30 | 40 | 41 | kowalczyk@symu.co 42 | 43 | 44 | 55 | 56 | ****************** 57 | 58 | 59 | 71 | 72 | LOG IN 73 | 74 | 75 | 76 | 77 | 78 | ); 79 | } 80 | } 81 | 82 | export default Login; 83 | -------------------------------------------------------------------------------- /euroBet/screen/Matches/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | Image, 6 | ScrollView, 7 | StatusBar, 8 | ImageBackground, 9 | TouchableOpacity 10 | } from "react-native"; 11 | 12 | import { Block, Text } from "../../components"; 13 | import * as theme from "../../theme"; 14 | import * as mock from "../../mock"; 15 | 16 | class Matches extends React.Component { 17 | changeScreen = (i, epoch) => { 18 | i.epoch = epoch; 19 | this.props.navigation.navigate("Overview", i); 20 | }; 21 | 22 | renderHeader() { 23 | return ( 24 | 25 | 32 | 36 | 37 | All Matches 38 | 39 | 43 | 44 | 45 | ); 46 | } 47 | 48 | renderGameCard(i, epoch, today, firstOfAll) { 49 | const { live, country, flag, adversary, advFlag, result } = i; 50 | 51 | return ( 52 | 64 | 65 | 66 | 69 | {country} 70 | 71 | 72 | 73 | {live ? ( 74 | 75 | {result} 76 | 77 | ) : today ? ( 78 | 79 | {result} 80 | 81 | ) : ( 82 | {result} 83 | )} 84 | 85 | 86 | 89 | {adversary} 90 | 91 | 92 | 93 | 94 | ); 95 | } 96 | 97 | renderMatches() { 98 | const { dates } = this.props; 99 | let firstOfAll = true; 100 | 101 | return ( 102 | 103 | {dates.map(item => { 104 | const { date, DOW, epoch, games } = item; 105 | 106 | const today = DOW === "TODAY"; 107 | 108 | let gamesComponent = games.map(i => { 109 | let component = this.renderGameCard(i, epoch, today, firstOfAll); 110 | 111 | if (firstOfAll) firstOfAll = false; 112 | 113 | return component; 114 | }); 115 | 116 | return ( 117 | 118 | 125 | {DOW + " | " + date} 126 | {epoch.toUpperCase()} 127 | 128 | {gamesComponent} 129 | 130 | ); 131 | })} 132 | 133 | ); 134 | } 135 | 136 | render() { 137 | return ( 138 | 139 | 140 | 150 | {this.renderHeader()} 151 | 158 | {this.renderMatches()} 159 | 160 | 161 | ); 162 | } 163 | } 164 | 165 | Matches.defaultProps = { 166 | dates: mock.dates 167 | }; 168 | 169 | const styles = StyleSheet.create({ 170 | flag: { 171 | height: 34 / 2, 172 | width: 34 / 2, 173 | shadowColor: theme.colors.black, 174 | shadowOffset: { width: 0, height: 0 }, 175 | shadowOpacity: 0.1, 176 | shadowRadius: 2 177 | } 178 | }); 179 | 180 | export default Matches; 181 | -------------------------------------------------------------------------------- /euroBet/screen/Overview/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | Image, 6 | ScrollView, 7 | StatusBar, 8 | ImageBackground, 9 | TouchableOpacity, 10 | RefreshControl 11 | } from "react-native"; 12 | 13 | import { Block, Text } from "../../components"; 14 | import * as theme from "../../theme"; 15 | import * as mock from "../../mock"; 16 | import SectionWithCards from "../../components/SectionWithCards"; 17 | 18 | const typeHelper = { 19 | yellow: { 20 | text: " gets a yellow card.", 21 | icon: ( 22 | 26 | ) 27 | }, 28 | substitution: { 29 | text: " is on for ", 30 | icon: ( 31 | 35 | ) 36 | }, 37 | goal: { 38 | text: " scores for ", 39 | icon: ( 40 | 44 | ) 45 | } 46 | }; 47 | 48 | const StatsGraphComponent = function(props) { 49 | const { n, total, sufix } = props; 50 | 51 | return ( 52 | 53 | 54 | {sufix ? n.toString() + sufix : n} 55 | 56 | 57 | 62 | 66 | 67 | 68 | ); 69 | }; 70 | 71 | const ChatBubble = function(props) { 72 | if (props.left) 73 | return ( 74 | 75 | 76 | 82 | {props.player} 83 | 84 | 92 | 98 | {props.time} 99 | 100 | 101 | 105 | 106 | ); 107 | 108 | return ( 109 | 110 | 114 | 115 | 121 | {props.time} 122 | 123 | 131 | 137 | {props.player} 138 | 139 | 140 | 141 | ); 142 | }; 143 | 144 | const Line = function(props) { 145 | let defaultH = props.h ? props.h : 30; 146 | 147 | const lineComponent = ( 148 | 156 | ); 157 | 158 | const ballComponent = ( 159 | 164 | ); 165 | 166 | if (props.start) 167 | return ( 168 | 169 | {ballComponent} 170 | {lineComponent} 171 | 172 | ); 173 | if (props.end) 174 | return ( 175 | 176 | {lineComponent} 177 | {ballComponent} 178 | 179 | ); 180 | return lineComponent; 181 | }; 182 | 183 | class Overview extends React.Component { 184 | state = { 185 | selectedTab: 0 186 | }; 187 | 188 | componentDidMount() { 189 | if (this.props.navigation.state.params.live) 190 | this.setState({ selectedTab: 1 }); 191 | } 192 | 193 | renderHeader() { 194 | const { 195 | advFlagx3, 196 | adversary, 197 | country, 198 | flagx3, 199 | live, 200 | result, 201 | epoch 202 | } = this.props.navigation.state.params; 203 | 204 | const { time } = this.props.liveStream; 205 | 206 | return ( 207 | 208 | 215 | this.props.navigation.goBack()}> 216 | 220 | 221 | 222 | Match Overview 223 | 224 | 228 | 229 | 240 | 241 | 242 | 243 | {country} 244 | 245 | 246 | 247 | 248 | {epoch} 249 | 250 | {result} 251 | 252 | {live ? ( 253 | 254 | {time} 255 | 256 | ) : ( 257 | 258 | {"End"} 259 | 260 | )} 261 | 262 | 263 | 264 | 265 | 266 | {adversary} 267 | 268 | 269 | 270 | 271 | ); 272 | } 273 | 274 | underConstruction() { 275 | return ( 276 | 277 | UnderConstruction 278 | 279 | ); 280 | } 281 | 282 | renderSelectTab() { 283 | return ( 284 | 285 | 290 | {[ 291 | "Lineup", 292 | "Live stream", 293 | "Highlights", 294 | "Stats", 295 | "Draw", 296 | "Bet now" 297 | ].map((i, n) => { 298 | const selected = this.state.selectedTab === n; 299 | 300 | return ( 301 | this.setState({ selectedTab: n })} 304 | key={n} 305 | > 306 | 307 | {i} 308 | 309 | 310 | ); 311 | })} 312 | 313 | 314 | ); 315 | } 316 | 317 | renderLiveStream() { 318 | const { moments } = this.props.liveStream; 319 | const { live } = this.props.navigation.state.params; 320 | 321 | let secondHalf = moments.length > 1; 322 | 323 | return ( 324 | 325 | {moments.map((item, index) => { 326 | const title = secondHalf ? "SECOND HALF" : "FIRST HALF"; 327 | secondHalf = false; 328 | 329 | let c = item.map((i, n) => { 330 | const { type, time, player } = i; 331 | const { text, icon } = typeHelper[type]; 332 | 333 | return ( 334 | 345 | 346 | {icon} 347 | 348 | {player} 349 | 350 | {text} 351 | {type === "goal" && ( 352 | 353 | {this.props.navigation.state.params[i.from] + "!"} 354 | 355 | )} 356 | {type === "substitution" && ( 357 | {i.out + "."} 358 | )} 359 | 360 | 361 | 362 | {time} 363 | 364 | 365 | ); 366 | }); 367 | 368 | return ; 369 | })} 370 | 371 | ); 372 | } 373 | 374 | renderHighlights() { 375 | const secondHalf = this.props.highlights.length > 1; 376 | 377 | return ( 378 | 379 | {this.props.highlights.map((item, index) => { 380 | let timeComp = item.map((i, n) => { 381 | if (!i) return; 382 | 383 | const { type, time, player, from } = i; 384 | const { icon } = typeHelper[type]; 385 | const left = from === "country"; 386 | 387 | const bubbleComp = ( 388 | 389 | ); 390 | 391 | return ( 392 | 393 | 394 | 395 | {left && bubbleComp} 396 | 397 | 398 | 399 | 410 | {icon} 411 | 412 | 413 | 414 | {!left && bubbleComp} 415 | 416 | 417 | ); 418 | }); 419 | 420 | return ( 421 | 426 | 427 | {timeComp} 428 | 429 | {secondHalf && index === 0 && ( 430 | HALF TIME 431 | )} 432 | 433 | ); 434 | })} 435 | START 436 | 437 | ); 438 | } 439 | 440 | renderStats() { 441 | let c = this.props.stats.map((item, index) => { 442 | const { title, icon, country, adversary, total } = item; 443 | const percentage = title === "Ball possesion"; 444 | 445 | return ( 446 | 459 | 464 | 465 | {icon} 466 | 467 | {title} 468 | 469 | 470 | 475 | 476 | ); 477 | }); 478 | 479 | return ; 480 | } 481 | 482 | render() { 483 | let content = this.underConstruction(); 484 | 485 | switch (this.state.selectedTab) { 486 | case 1: 487 | content = this.renderLiveStream(); 488 | break; 489 | case 2: 490 | content = this.renderHighlights(); 491 | break; 492 | case 3: 493 | content = this.renderStats(); 494 | break; 495 | } 496 | 497 | return ( 498 | 499 | 500 | 504 | {this.renderHeader()} 505 | {this.renderSelectTab()} 506 | this.setState({ refreshing: false })} 517 | /> 518 | } 519 | > 520 | {content} 521 | 522 | 523 | ); 524 | } 525 | } 526 | 527 | Overview.defaultProps = { 528 | liveStream: mock.liveStream, 529 | stats: mock.stats, 530 | highlights: mock.highlights 531 | }; 532 | 533 | const styles = StyleSheet.create({ 534 | bg: { 535 | width: "101%", 536 | height: "101%", 537 | position: "absolute", 538 | left: -5, 539 | top: -5 540 | }, 541 | flag: { 542 | height: 93 / 2, 543 | width: 93 / 2 544 | } 545 | }); 546 | 547 | export default Overview; 548 | -------------------------------------------------------------------------------- /euroBet/screen/Top/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | ScrollView, 6 | RefreshControl, 7 | Image, 8 | TouchableOpacity 9 | } from "react-native"; 10 | 11 | import { Block, Text } from "../../components"; 12 | import * as theme from "../../theme"; 13 | import * as mock from "../../mock"; 14 | import SectionWithCards from "../../components/SectionWithCards"; 15 | 16 | class Top extends React.Component { 17 | state = { 18 | selectedTab: 1 19 | }; 20 | 21 | renderHeader() { 22 | const { title, goals, club, assists } = this.props; 23 | 24 | return ( 25 | 26 | 33 | 37 | 38 | Top players 39 | 40 | 44 | 45 | 46 | 50 | 51 | 58 | 59 | 60 | {goals} 61 | 62 | GOALS 63 | 64 | 65 | 66 | {title} 67 | 68 | {club} 69 | 70 | 71 | 72 | {assists} 73 | 74 | ASSISTS 75 | 76 | 77 | 78 | 79 | ); 80 | } 81 | 82 | underConstruction() { 83 | return ( 84 | 85 | UnderConstruction 86 | 87 | ); 88 | } 89 | 90 | renderSelectTab() { 91 | return ( 92 | 93 | 98 | {[ 99 | "Overall", 100 | "Top Scorers", 101 | "Assists", 102 | "Top speed", 103 | "Most valued" 104 | ].map((i, n) => { 105 | const selected = this.state.selectedTab === n; 106 | 107 | return ( 108 | this.setState({ selectedTab: n })} 111 | key={n} 112 | > 113 | 114 | {i} 115 | 116 | 117 | ); 118 | })} 119 | 120 | 121 | ); 122 | } 123 | 124 | renderTopScores() { 125 | let c = this.props.topScores.map((item, index) => { 126 | const { name, goals } = item; 127 | return ( 128 | 141 | {index + 2} 142 | 143 | {name} 144 | 145 | {goals} 146 | 147 | ); 148 | }); 149 | 150 | return ; 151 | } 152 | 153 | render() { 154 | let content = this.underConstruction(); 155 | 156 | switch (this.state.selectedTab) { 157 | case 1: 158 | content = this.renderTopScores(); 159 | break; 160 | } 161 | 162 | return ( 163 | 164 | {this.renderHeader()} 165 | {this.renderSelectTab()} 166 | this.setState({ refreshing: false })} 177 | /> 178 | } 179 | > 180 | {content} 181 | 182 | 183 | 184 | ); 185 | } 186 | } 187 | 188 | Top.defaultProps = { 189 | title: "Gareth Bale", 190 | club: "WALES", 191 | goals: 8, 192 | assists: 2, 193 | topScores: mock.top 194 | }; 195 | 196 | export default Top; 197 | -------------------------------------------------------------------------------- /euroBet/screen/UnderConstruction.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text } from "react-native"; 3 | 4 | export default class UnderConstruction extends React.Component { 5 | render() { 6 | return ( 7 | 14 | 15 | {"Sadly, this screen is not implemented yet."} 16 | 17 | 18 | {"You can help me improve this project by forking it.\n"} 19 | 20 | 21 | {"Any help is appreciated! :)"} 22 | 23 | 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /euroBet/screen/navigate.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Image } from "react-native"; 3 | import { 4 | createBottomTabNavigator, 5 | createSwitchNavigator, 6 | createAppContainer, 7 | createStackNavigator 8 | } from "react-navigation"; 9 | 10 | import * as theme from "../theme"; 11 | 12 | import Matches from "./Matches"; 13 | import Overview from "./Overview"; 14 | import Top from "./Top"; 15 | import Login from "./Login"; 16 | import UnderConstruction from "./UnderConstruction"; 17 | 18 | const MatchesScreenStack = createStackNavigator( 19 | { 20 | Matches: { screen: Matches }, 21 | Overview: { screen: Overview } 22 | }, 23 | { 24 | initialRoute: "Matches", 25 | cardStyle: { 26 | shadowColor: "transparent", 27 | backgroundColor: "transparent" 28 | }, 29 | headerMode: "none" 30 | } 31 | ); 32 | 33 | const TabContainer = createBottomTabNavigator( 34 | { 35 | Matches: { 36 | screen: MatchesScreenStack, 37 | navigationOptions: { 38 | tabBarIcon: tab => ( 39 | 47 | ) 48 | } 49 | }, 50 | "Top Players": { 51 | screen: Top, 52 | navigationOptions: { 53 | tabBarIcon: tab => ( 54 | 62 | ) 63 | } 64 | }, 65 | Favorites: { 66 | screen: UnderConstruction, 67 | navigationOptions: { 68 | tabBarIcon: tab => ( 69 | 77 | ) 78 | } 79 | }, 80 | Settings: { 81 | screen: UnderConstruction, 82 | navigationOptions: { 83 | tabBarIcon: tab => ( 84 | 92 | ) 93 | } 94 | } 95 | }, 96 | { 97 | initialRouteName: "Matches", 98 | 99 | tabBarOptions: { 100 | activeTintColor: theme.colors.primary, 101 | style: { 102 | borderTopWidth: 0 103 | } 104 | } 105 | } 106 | ); 107 | 108 | const AppContainer = createSwitchNavigator( 109 | { 110 | Login, 111 | App: TabContainer 112 | }, 113 | { initialRouteName: "Login" } 114 | ); 115 | 116 | export default createAppContainer(AppContainer); 117 | -------------------------------------------------------------------------------- /euroBet/theme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | primary: '#233A59', 3 | secondary: '#ABB5C4', 4 | gray: '#8F8F8F', 5 | black: '#000', 6 | white: '#FFF', 7 | }; 8 | 9 | const sizes = { 10 | // global sizes 11 | font: 11, 12 | border: 20, 13 | 14 | // font sizes 15 | title: 18, 16 | h1: 15, 17 | h2: 13, 18 | small: 10, 19 | }; 20 | 21 | const fonts = { 22 | h1: { 23 | fontSize: sizes.h1, 24 | }, 25 | h2: { 26 | fontSize: sizes.h2, 27 | }, 28 | small: { 29 | fontSize: sizes.small, 30 | }, 31 | title: { 32 | fontSize: sizes.title, 33 | }, 34 | }; 35 | 36 | export { colors, fonts, sizes }; -------------------------------------------------------------------------------- /heyU/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActivityIndicator, Image, StatusBar } from 'react-native'; 3 | 4 | import { Asset } from 'expo-asset'; 5 | import * as Font from 'expo-font'; 6 | 7 | import { Block } from './components'; 8 | 9 | import Navigator from './screen/navigate'; 10 | 11 | function loadIcons(images) { 12 | return images.map((image) => { 13 | if (typeof image === 'string') { 14 | return Image.prefetch(image); 15 | } else { 16 | return Asset.fromModule(image).downloadAsync(); 17 | } 18 | }); 19 | } 20 | 21 | export default class App extends React.Component { 22 | state = { 23 | iconsLoaded: false, 24 | }; 25 | 26 | async componentDidMount() { 27 | const imageAssets = loadIcons([ 28 | require('./assets/delete.png'), 29 | require('./assets/emoji.png'), 30 | require('./assets/icon.png'), 31 | require('./assets/info.png'), 32 | require('./assets/black-info.png'), 33 | require('./assets/message.png'), 34 | require('./assets/more-horizontal.png'), 35 | require('./assets/more.png'), 36 | require('./assets/power.png'), 37 | require('./assets/profile.png'), 38 | require('./assets/right-arrow.png'), 39 | require('./assets/left-arrow.png'), 40 | require('./assets/search.png'), 41 | require('./assets/search-mini.png'), 42 | require('./assets/send.png'), 43 | require('./assets/plus.png'), 44 | require('./assets/splash.png'), 45 | require('./assets/user1-mini.png'), 46 | require('./assets/user1.png'), 47 | require('./assets/user1x2.png'), 48 | require('./assets/user1x3.png'), 49 | require('./assets/user2.png'), 50 | require('./assets/user2x2.png'), 51 | require('./assets/user2x3.png'), 52 | require('./assets/user3.png'), 53 | require('./assets/user3x2.png'), 54 | require('./assets/user3x3.png'), 55 | require('./assets/user4.png'), 56 | require('./assets/user4x2.png'), 57 | require('./assets/user4x3.png'), 58 | require('./assets/user5.png'), 59 | require('./assets/user5x2.png'), 60 | require('./assets/user5x3.png'), 61 | require('./assets/user6.png'), 62 | require('./assets/user6x2.png'), 63 | require('./assets/user6x3.png'), 64 | require('./assets/user7.png'), 65 | require('./assets/user7x2.png'), 66 | require('./assets/user7x3.png'), 67 | require('./assets/user8.png'), 68 | require('./assets/user8x2.png'), 69 | require('./assets/user8x3.png'), 70 | ]); 71 | 72 | await Font.loadAsync({ 73 | 'Lato-Regular': require('./assets/fonts/Lato-Regular.ttf'), 74 | 'Lato-Bold': require('./assets/fonts/Lato-Bold.ttf'), 75 | 'Lato-Black': require('./assets/fonts/Lato-Black.ttf'), 76 | 'Lato-Semibold': require('./assets/fonts/Lato-Semibold.ttf'), 77 | }); 78 | 79 | await Promise.all([...imageAssets]).then(() => 80 | this.setState({ iconsLoaded: true }) 81 | ); 82 | } 83 | 84 | render() { 85 | if (!this.state.iconsLoaded) { 86 | return ( 87 | 88 | 89 | 90 | 91 | ); 92 | } 93 | return ; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /heyU/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 |

7 |

8 | 9 | 10 | 11 |

12 |

13 | 14 |

15 | 16 | # HeyU Mobile App 17 | 18 | built with [React Native](https://github.com/facebook/react-native) and [Expo](https://github.com/expo/expo). 19 | 20 | ## Installation 21 | 22 | - Clone this repo `git clone https://github.com/dev-andremonteiro/react-native-frontend-adventure.git` 23 | - `cd react-native-frontend-adventure` 24 | - `cd heyU` 25 | - run `npm install` 26 | - run `expo start` 27 | 28 | ## Design 29 | 30 | Props to Jakub at Team [Spoko](http://spoko.io/) 31 | 32 | - [Dribbble](https://dribbble.com/jakubkowalczyk) 33 | - [Twitter](https://twitter.com/jakubdesign) 34 | - [Behance](https://www.behance.net/jakubkowalczyk) 35 | 36 | Show some :heart: for the designer that made this possible 37 | 38 | ## Help me 39 | 40 | - [ ] How to align chat messages without linebreak ( Chat screen ) 41 | 42 | - [ ] Change switch activate color to Gradient, somehow I need to pass 43 | a gradient color to the property of the switch. 44 | 45 | - [ ] Scale ImageNofified with Image size. 46 | 47 | ## Developer 48 | 49 | Andre Monteiro [dev-andremonteiro](https://github.com/dev-andremonteiro) 50 | 51 | [Follow me on Twitter](https://twitter.com/DAndremonteiro) :) 52 | -------------------------------------------------------------------------------- /heyU/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "HeyU", 4 | "slug": "heyu", 5 | "privacy": "public", 6 | "platforms": [ 7 | "ios", 8 | "android" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | }, 27 | "description": "Part of the front end advetures using React Native and Expo", 28 | "githubUrl": "https://github.com/dev-andremonteiro/react-native-frontend-adventure" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /heyU/assets/black-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/black-info.png -------------------------------------------------------------------------------- /heyU/assets/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/delete.png -------------------------------------------------------------------------------- /heyU/assets/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/emoji.png -------------------------------------------------------------------------------- /heyU/assets/fonts/Lato-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/fonts/Lato-Black.ttf -------------------------------------------------------------------------------- /heyU/assets/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /heyU/assets/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /heyU/assets/fonts/Lato-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/fonts/Lato-Semibold.ttf -------------------------------------------------------------------------------- /heyU/assets/fonts/lato.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/fonts/lato.zip -------------------------------------------------------------------------------- /heyU/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/icon.png -------------------------------------------------------------------------------- /heyU/assets/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/info.png -------------------------------------------------------------------------------- /heyU/assets/left-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/left-arrow.png -------------------------------------------------------------------------------- /heyU/assets/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/message.png -------------------------------------------------------------------------------- /heyU/assets/more-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/more-horizontal.png -------------------------------------------------------------------------------- /heyU/assets/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/more.png -------------------------------------------------------------------------------- /heyU/assets/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/plus.png -------------------------------------------------------------------------------- /heyU/assets/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/power.png -------------------------------------------------------------------------------- /heyU/assets/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/profile.png -------------------------------------------------------------------------------- /heyU/assets/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/right-arrow.png -------------------------------------------------------------------------------- /heyU/assets/search-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/search-mini.png -------------------------------------------------------------------------------- /heyU/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/search.png -------------------------------------------------------------------------------- /heyU/assets/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/send.png -------------------------------------------------------------------------------- /heyU/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/splash.png -------------------------------------------------------------------------------- /heyU/assets/user1-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user1-mini.png -------------------------------------------------------------------------------- /heyU/assets/user1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user1.png -------------------------------------------------------------------------------- /heyU/assets/user1x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user1x2.png -------------------------------------------------------------------------------- /heyU/assets/user1x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user1x3.png -------------------------------------------------------------------------------- /heyU/assets/user2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user2.png -------------------------------------------------------------------------------- /heyU/assets/user2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user2x2.png -------------------------------------------------------------------------------- /heyU/assets/user2x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user2x3.png -------------------------------------------------------------------------------- /heyU/assets/user3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user3.png -------------------------------------------------------------------------------- /heyU/assets/user3x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user3x2.png -------------------------------------------------------------------------------- /heyU/assets/user3x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user3x3.png -------------------------------------------------------------------------------- /heyU/assets/user4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user4.png -------------------------------------------------------------------------------- /heyU/assets/user4x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user4x2.png -------------------------------------------------------------------------------- /heyU/assets/user4x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user4x3.png -------------------------------------------------------------------------------- /heyU/assets/user5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user5.png -------------------------------------------------------------------------------- /heyU/assets/user5x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user5x2.png -------------------------------------------------------------------------------- /heyU/assets/user5x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user5x3.png -------------------------------------------------------------------------------- /heyU/assets/user6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user6.png -------------------------------------------------------------------------------- /heyU/assets/user6x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user6x2.png -------------------------------------------------------------------------------- /heyU/assets/user6x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user6x3.png -------------------------------------------------------------------------------- /heyU/assets/user7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user7.png -------------------------------------------------------------------------------- /heyU/assets/user7x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user7x2.png -------------------------------------------------------------------------------- /heyU/assets/user7x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user7x3.png -------------------------------------------------------------------------------- /heyU/assets/user8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user8.png -------------------------------------------------------------------------------- /heyU/assets/user8x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user8x2.png -------------------------------------------------------------------------------- /heyU/assets/user8x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/heyU/assets/user8x3.png -------------------------------------------------------------------------------- /heyU/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /heyU/components/Block.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { StyleSheet, View } from "react-native"; 3 | 4 | import { colors, sizes } from "../theme"; 5 | 6 | export default class Block extends Component { 7 | render() { 8 | const { 9 | flex, 10 | row, 11 | column, 12 | center, 13 | middle, 14 | left, 15 | right, 16 | card, 17 | shadow, 18 | color, 19 | white, 20 | space, 21 | style, 22 | children, 23 | ...props 24 | } = this.props; 25 | 26 | const blockStyles = [ 27 | styles.block, 28 | flex && { flex }, 29 | flex === false && { flex: 0 }, // reset / disable flex 30 | row && styles.row, 31 | column && styles.column, 32 | center && styles.center, 33 | middle && styles.middle, 34 | left && styles.left, 35 | right && styles.right, 36 | card && styles.card, 37 | shadow && styles.shadow, 38 | space && { justifyContent: `space-${space}` }, 39 | white && styles.white, 40 | color && styles[color], // predefined styles colors for backgroundColor 41 | color && !styles[color] && { backgroundColor: color }, // custom backgroundColor 42 | style // rewrite predefined styles 43 | ]; 44 | 45 | return ( 46 | 47 | {children} 48 | 49 | ); 50 | } 51 | } 52 | 53 | const styles = StyleSheet.create({ 54 | block: { 55 | flex: 1 56 | }, 57 | row: { 58 | flexDirection: "row" 59 | }, 60 | column: { 61 | flexDirection: "column" 62 | }, 63 | card: { 64 | borderRadius: sizes.border 65 | }, 66 | center: { 67 | alignItems: "center" 68 | }, 69 | middle: { 70 | justifyContent: "center" 71 | }, 72 | left: { 73 | justifyContent: "flex-start" 74 | }, 75 | right: { 76 | justifyContent: "flex-end" 77 | }, 78 | shadow: { 79 | shadowColor: colors.black, 80 | shadowOffset: { width: -3, height: 3 }, 81 | shadowOpacity: 0.1, 82 | shadowRadius: 5 83 | }, 84 | white: { backgroundColor: colors.white } 85 | }); 86 | -------------------------------------------------------------------------------- /heyU/components/ImageNotify.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Image, View } from 'react-native'; 3 | 4 | import { LinearGradient } from 'expo-linear-gradient'; 5 | 6 | export default class ImageNotify extends Component { 7 | state = { 8 | imageSize: 50, 9 | topOffset: 35, 10 | leftOffset: 35, 11 | whiteBallSize: 14, 12 | colorBallSize: 10, 13 | }; 14 | 15 | componentWillMount() { 16 | if (this.props.size === 'small') { 17 | this.setState({ 18 | imageSize: 32, 19 | topOffset: 24, 20 | leftOffset: 22, 21 | whiteBallSize: 10, 22 | colorBallSize: 7, 23 | }); 24 | } 25 | } 26 | 27 | render() { 28 | return ( 29 | 30 | 34 | 42 | 52 | 62 | 63 | 64 | 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /heyU/components/Text.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Text, StyleSheet } from "react-native"; 3 | 4 | import { sizes, colors, fonts } from "../theme"; 5 | 6 | export default class Typography extends Component { 7 | render() { 8 | const { 9 | title, 10 | h1, 11 | h2, 12 | small, 13 | size, 14 | // styling 15 | bold, 16 | center, 17 | right, 18 | // colors 19 | color, 20 | black, 21 | white, 22 | primary, 23 | secondary, 24 | style, 25 | children, 26 | ...props 27 | } = this.props; 28 | 29 | const textStyles = [ 30 | styles.text, 31 | title && styles.title, 32 | h1 && styles.h1, 33 | h2 && styles.h2, 34 | small && styles.small, 35 | size && { fontSize: size }, 36 | bold && styles.bold, 37 | center && styles.center, 38 | right && styles.right, 39 | color && styles[color], 40 | color && !styles[color] && { color }, 41 | // color shortcuts 42 | primary && styles.primary, 43 | secondary && styles.secondary, 44 | black && styles.black, 45 | white && styles.white, 46 | style // rewrite predefined styles 47 | ]; 48 | 49 | return ( 50 | 51 | {children} 52 | 53 | ); 54 | } 55 | } 56 | 57 | const styles = StyleSheet.create({ 58 | // default style 59 | text: { 60 | fontFamily: "Lato-Regular", 61 | fontSize: sizes.font, 62 | color: colors.secondary 63 | }, 64 | // variations 65 | bold: { 66 | fontFamily: "Lato-Bold" 67 | }, 68 | // position 69 | center: { textAlign: "center" }, 70 | right: { textAlign: "right" }, 71 | // colors 72 | secondary: { color: colors.secondary }, 73 | primary: { color: colors.primary }, 74 | black: { color: colors.black }, 75 | white: { color: colors.white }, 76 | gray: { color: colors.gray }, 77 | // fonts 78 | title: fonts.title, 79 | h1: fonts.h1, 80 | h2: fonts.h2, 81 | small: fonts.small 82 | }); 83 | -------------------------------------------------------------------------------- /heyU/components/index.js: -------------------------------------------------------------------------------- 1 | import Block from "./Block"; 2 | import Text from "./Text"; 3 | import ImageNotify from "./ImageNotify"; 4 | 5 | export { Block, Text, ImageNotify }; 6 | -------------------------------------------------------------------------------- /heyU/mock.js: -------------------------------------------------------------------------------- 1 | export const messages = [ 2 | { 3 | icon: require("./assets/user1x3.png"), 4 | name: "Oswald Cobblepot", 5 | lastMessage: "I'm the King of Gotham", 6 | time: "7:03 PM" 7 | }, 8 | { 9 | icon: require("./assets/user2x3.png"), 10 | name: "Fish Mooney", 11 | lastMessage: 'Please don\'t call me "babes".', 12 | time: "5:35 PM" 13 | }, 14 | { 15 | icon: require("./assets/user3x3.png"), 16 | name: "Bruce Wayne", 17 | lastMessage: "Sometimes the right way is also the ugly way..", 18 | time: "8:50 AM" 19 | }, 20 | { 21 | icon: require("./assets/user4x3.png"), 22 | name: "Barbara Kean", 23 | lastMessage: "It's Gotham, baby, we've all got flair!", 24 | time: "Yesterday", 25 | notification: true 26 | }, 27 | { 28 | icon: require("./assets/user5x3.png"), 29 | name: "Edward Nygma", 30 | lastMessage: "No body, no crime.", 31 | time: "Yesterday" 32 | }, 33 | { 34 | icon: require("./assets/user6x3.png"), 35 | name: "Selina Kyle", 36 | lastMessage: "Cat got your tongue?", 37 | time: "Sunday" 38 | }, 39 | { 40 | icon: require("./assets/user7x3.png"), 41 | name: "Harvey Bullock", 42 | lastMessage: "I thought I was supposed to be the bad guy here?", 43 | time: "Saturday", 44 | notification: true 45 | }, 46 | { 47 | icon: require("./assets/user8x3.png"), 48 | name: "Jim Gordon", 49 | lastMessage: "Nice, you saw this :D", 50 | time: "Saturday", 51 | notification: true 52 | } 53 | ]; 54 | 55 | export const chat = [ 56 | { message: "Mr. Cobblepot. Nice to\nmeet you!" }, 57 | { message: "Call me Penguin.", hour: "7:00PM", from: true }, 58 | { message: "I thought I heard you\nhated that name." }, 59 | { message: "It grew on me ", hour: "7:03PM", from: true }, 60 | { message: "Penguin, it is" }, 61 | { message: "...", from: true } 62 | ]; 63 | 64 | export const groups = [ 65 | { 66 | name: "Gotham City Police Department", 67 | last: "5 minutes ago", 68 | icons: [ 69 | require("./assets/user7.png"), 70 | require("./assets/user4.png"), 71 | require("./assets/user6.png"), 72 | require("./assets/user8.png") 73 | ] 74 | }, 75 | { 76 | name: "Gotham City Police Department", 77 | last: "2 days ago", 78 | icons: [ 79 | require("./assets/user1.png"), 80 | require("./assets/user4.png"), 81 | require("./assets/user6.png"), 82 | require("./assets/user8.png"), 83 | require("./assets/user7.png") 84 | ] 85 | }, 86 | { 87 | name: "Falcone Crime Family", 88 | last: "Saturday", 89 | icons: [ 90 | require("./assets/user5.png"), 91 | require("./assets/user1.png"), 92 | require("./assets/user4.png"), 93 | require("./assets/user6.png"), 94 | require("./assets/user8.png"), 95 | require("./assets/user7.png"), 96 | require("./assets/user2.png") 97 | ] 98 | }, 99 | { 100 | name: "Arkham Asylum", 101 | last: "Saturday", 102 | icons: [require("./assets/user7.png"), require("./assets/user8.png")] 103 | } 104 | ]; 105 | 106 | export const contacts = [ 107 | { 108 | icon: require("./assets/user1x2.png"), 109 | name: "Oswald Cobblepot", 110 | online: true 111 | }, 112 | { icon: require("./assets/user6x2.png"), name: "Selina Kyle" }, 113 | { icon: require("./assets/user2x2.png"), name: "Fish Mooney", online: true }, 114 | { icon: require("./assets/user3x2.png"), name: "Bruce Wayne", online: true }, 115 | { icon: require("./assets/user7x2.png"), name: "Harvey Bullock" }, 116 | { icon: require("./assets/user4x2.png"), name: "Barbara Kean", online: true }, 117 | { icon: require("./assets/user8x2.png"), name: "Jim Gordon" }, 118 | { icon: require("./assets/user1x2.png"), name: "Filler" }, 119 | { icon: require("./assets/user5x2.png"), name: "Edward Nygma", online: true } 120 | ]; 121 | 122 | export const profile = { 123 | icon: require("./assets/profile.png"), 124 | name: "John Doe", 125 | description: 126 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 127 | email: "johndoe@symu.co", 128 | telephone: "00 222 333 444", 129 | notifications: true 130 | }; 131 | -------------------------------------------------------------------------------- /heyU/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "eject": "expo eject" 8 | }, 9 | "dependencies": { 10 | "expo": "^40.0.0", 11 | "expo-asset": "~8.2.1", 12 | "expo-font": "~8.4.0", 13 | "expo-linear-gradient": "~8.4.0", 14 | "react": "16.13.1", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz", 16 | "react-native-gesture-handler": "~1.8.0", 17 | "react-native-screens": "~2.15.2", 18 | "react-native-swipeout": "^2.3.6", 19 | "react-navigation": "^3.3.2" 20 | }, 21 | "devDependencies": { 22 | "babel-preset-expo": "8.3.0" 23 | }, 24 | "private": true 25 | } 26 | -------------------------------------------------------------------------------- /heyU/screen/Chat/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Image, 4 | KeyboardAvoidingView, 5 | SafeAreaView, 6 | ScrollView, 7 | StyleSheet, 8 | TextInput, 9 | TouchableOpacity, 10 | } from 'react-native'; 11 | 12 | import { LinearGradient } from 'expo-linear-gradient'; 13 | 14 | import { Block, Text } from '../../components'; 15 | import { chat } from '../../mock'; 16 | import { colors, GradientIcon, sizes } from '../../theme'; 17 | 18 | export default class Chat extends React.Component { 19 | static navigationOptions = ({ navigation }) => { 20 | return { 21 | header: ( 22 | 29 | 38 | navigation.goBack()} 45 | hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }} 46 | > 47 | 51 | 52 | 53 | {navigation.state.params.name} 54 | 55 | 56 | 60 | 61 | 62 | 63 | ), 64 | }; 65 | }; 66 | 67 | state = { text: '', messages: [], getUp: false }; 68 | 69 | componentWillMount = () => { 70 | this.setState({ messages: this.props.chat }); 71 | }; 72 | 73 | sendMessage = () => { 74 | let messages = this.state.messages; 75 | messages.push({ message: this.state.text }); 76 | this.setState({ text: '', messages }); 77 | }; 78 | 79 | render() { 80 | const { icon, miniIcon } = this.props; 81 | 82 | return ( 83 | 84 | { 86 | this.scrollView = ref; 87 | }} 88 | showsVerticalScrollIndicator={false} 89 | style={{ flex: 1 }} 90 | scrollEventThrottle={16} 91 | contentContainerStyle={{ 92 | paddingTop: 20, 93 | paddingHorizontal: 10, 94 | }} 95 | > 96 | {this.state.messages.map((item, index) => { 97 | const { message, from, hour } = item; 98 | 99 | let messageComponent = null; 100 | 101 | if (from) { 102 | messageComponent = ( 103 | 104 | 108 | 109 | 121 | {message} 122 | {index === 3 && ( 123 | 127 | )} 128 | 129 | {hour && {hour}} 130 | 131 | ); 132 | } else { 133 | messageComponent = ( 134 | 135 | 139 | 148 | {message} 149 | 150 | {index === 4 ? ( 151 | 155 | ) : ( 156 | 160 | )} 161 | 162 | 163 | ); 164 | } 165 | 166 | return messageComponent; 167 | })} 168 | 169 | 174 | 175 | this.setState({ text })} 184 | value={this.state.text} 185 | placeholder={'Your message...'} 186 | placeholderTextColor={colors.secondary} 187 | clearTextOnFocus 188 | onFocus={() => { 189 | this.scrollView.scrollTo({ x: 0, y: 180 }); 190 | }} 191 | /> 192 | 193 | 197 | 208 | 212 | 213 | 214 | 215 | 216 | ); 217 | } 218 | } 219 | 220 | Chat.defaultProps = { 221 | chat: chat, 222 | icon: require('../../assets/user1.png'), 223 | miniIcon: require('../../assets/user1-mini.png'), 224 | }; 225 | -------------------------------------------------------------------------------- /heyU/screen/Contacts/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SafeAreaView, StyleSheet, Image, ScrollView } from "react-native"; 3 | import { Block, Text, ImageNotify } from "../../components"; 4 | import { colors, GradientText, GradientIcon, sizes } from "../../theme"; 5 | import { contacts } from "../../mock"; 6 | 7 | const Item = props => ( 8 | 20 | 21 | 22 | 23 | {props.name} 24 | 25 | 26 | 30 | 34 | 35 | ); 36 | 37 | export default class Contacts extends React.Component { 38 | constructor(props) { 39 | super(props); 40 | this.state = { 41 | online: [], 42 | others: [] 43 | }; 44 | } 45 | 46 | componentWillMount = () => { 47 | let online = []; 48 | let others = []; 49 | 50 | this.props.contacts.forEach(e => 51 | e.online ? online.push(e) : others.push(e) 52 | ); 53 | this.setState({ online, others }); 54 | }; 55 | 56 | renderHeader = () => ( 57 | 64 | 74 | 77 | Edit 78 | 79 | 80 | Contacts 81 | 82 | 83 | 87 | 88 | 89 | 90 | ); 91 | 92 | renderSearch() { 93 | return ( 94 | 95 | 104 | 108 | Search friends 109 | 110 | 111 | ); 112 | } 113 | 114 | renderCards(from) { 115 | let x = from === "online"; 116 | let componentData = x ? this.state.online : this.state.others; 117 | 118 | return ( 119 | 120 | {x ? ( 121 | 122 | {"Online ("} 123 | 124 | {this.state.online.length} 125 | 126 | {")"} 127 | 128 | ) : ( 129 | 130 | Others 131 | 132 | )} 133 | 134 | {componentData.map((item, index) => ( 135 | 141 | ))} 142 | 143 | ); 144 | } 145 | 146 | render() { 147 | return ( 148 | 149 | {this.renderHeader()} 150 | {this.renderSearch()} 151 | 156 | {this.state.online.length > 0 && this.renderCards("online")} 157 | {this.renderCards("other")} 158 | 159 | 160 | ); 161 | } 162 | } 163 | 164 | Contacts.defaultProps = { 165 | contacts: contacts 166 | }; 167 | 168 | const styles = StyleSheet.create({ 169 | title: { 170 | paddingHorizontal: 10, 171 | paddingVertical: 5, 172 | borderBottomColor: "#ccc", 173 | borderBottomWidth: StyleSheet.hairlineWidth 174 | } 175 | }); 176 | -------------------------------------------------------------------------------- /heyU/screen/Groups/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SafeAreaView, StyleSheet, Image, ScrollView } from "react-native"; 3 | import { Block, Text } from "../../components"; 4 | import { sizes, colors, GradientText, GradientIcon } from "../../theme"; 5 | import { groups } from "../../mock"; 6 | 7 | export default class Groups extends React.Component { 8 | renderHeader = () => ( 9 | 16 | 26 | 29 | Edit 30 | 31 | 32 | Groups 33 | 34 | 35 | 39 | 40 | 41 | 42 | ); 43 | 44 | render() { 45 | return ( 46 | 47 | {this.renderHeader()} 48 | 57 | {this.props.groups.map((item, index) => { 58 | const { name, last, icons } = item; 59 | const memberNumber = icons.length; 60 | 61 | return ( 62 | 69 | 70 | 79 | 80 | {name} 81 | 82 | 89 | {last} 90 | 100 | {memberNumber + " members"} 101 | 102 | 103 | {icons.map((i, n) => ( 104 | 109 | ))} 110 | 111 | 112 | 113 | ); 114 | })} 115 | 116 | 117 | ); 118 | } 119 | } 120 | 121 | Groups.defaultProps = { 122 | groups: groups 123 | }; 124 | -------------------------------------------------------------------------------- /heyU/screen/Login/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StatusBar, TouchableOpacity } from 'react-native'; 3 | 4 | import { LinearGradient } from 'expo-linear-gradient'; 5 | 6 | import { Block, Text } from '../../components'; 7 | import { GradientText } from '../../theme'; 8 | 9 | class Login extends React.Component { 10 | changeScreen = () => this.props.navigation.navigate('App'); 11 | 12 | render() { 13 | return ( 14 | 20 | 21 | 22 | 23 | HeyU 24 | 25 | 26 | Free chat app template 27 | 28 | 35 | 36 | johndoe@symu.co 37 | 38 | 39 | 46 | 47 | ***************** 48 | 49 | 50 | 54 | 55 | Sign up 56 | 57 | 58 | 59 | Already have an account? Sign in 60 | 61 | 62 | 63 | ); 64 | } 65 | } 66 | 67 | export default Login; 68 | -------------------------------------------------------------------------------- /heyU/screen/Messages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Image, 4 | SafeAreaView, 5 | ScrollView, 6 | StatusBar, 7 | StyleSheet, 8 | TouchableOpacity, 9 | } from 'react-native'; 10 | import Swipeout from 'react-native-swipeout'; 11 | 12 | import { LinearGradient } from 'expo-linear-gradient'; 13 | 14 | import { Block, ImageNotify, Text } from '../../components'; 15 | import { messages } from '../../mock'; 16 | import { GradientIcon, GradientText, sizes } from '../../theme'; 17 | 18 | const swipeoutBtns = [ 19 | { 20 | component: ( 21 | 22 | 26 | More 27 | 28 | ), 29 | }, 30 | { 31 | component: ( 32 | 43 | 47 | Delete 48 | 49 | ), 50 | }, 51 | ]; 52 | 53 | export default class Messages extends React.Component { 54 | static navigationOptions = ({ navigation }) => { 55 | return { 56 | header: ( 57 | 64 | 73 | 76 | Edit 77 | 78 | 79 | Messages 80 | 81 | 82 | 86 | 87 | 88 | 89 | ), 90 | }; 91 | }; 92 | 93 | changeScreen = (i) => { 94 | this.props.navigation.navigate('Chat', i); 95 | }; 96 | 97 | render() { 98 | return ( 99 | 100 | 101 | 107 | {this.props.messages.map((item) => { 108 | const { icon, name, lastMessage, time, notification } = item; 109 | 110 | return ( 111 | 117 | 127 | 128 | 129 | 130 | 131 | {name} 132 | 133 | {time} 134 | 135 | 136 | {lastMessage} 137 | 138 | 139 | 140 | 141 | ); 142 | })} 143 | 144 | 145 | ); 146 | } 147 | } 148 | 149 | Messages.defaultProps = { 150 | messages: messages, 151 | }; 152 | -------------------------------------------------------------------------------- /heyU/screen/Profile/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Image, 4 | SafeAreaView, 5 | ScrollView, 6 | StatusBar, 7 | StyleSheet, 8 | Switch, 9 | } from 'react-native'; 10 | 11 | import { LinearGradient } from 'expo-linear-gradient'; 12 | 13 | import { Block, Text } from '../../components'; 14 | import { profile } from '../../mock'; 15 | import { GradientText, sizes } from '../../theme'; 16 | 17 | class Item extends React.Component { 18 | render() { 19 | const { title, text, custom, paintTitle } = this.props; 20 | 21 | return ( 22 | 34 | {paintTitle ? ( 35 | 36 | {title} 37 | 38 | ) : ( 39 | 40 | {title} 41 | 42 | )} 43 | 44 | {text && !custom && {text}} 45 | {custom 46 | ? custom 47 | : !paintTitle && ( 48 | 52 | )} 53 | 54 | 55 | ); 56 | } 57 | } 58 | 59 | export default class Profile extends React.Component { 60 | state = { 61 | switch: false, 62 | }; 63 | 64 | componentDidMount() { 65 | this.setState({ switch: this.props.info.notifications }); 66 | 67 | this._navListener1 = this.props.navigation.addListener('willFocus', () => 68 | StatusBar.setBarStyle('light-content') 69 | ); 70 | this._navListener2 = this.props.navigation.addListener('willBlur', () => 71 | StatusBar.setBarStyle('default') 72 | ); 73 | } 74 | 75 | componentWillUnmount() { 76 | this._navListener1.remove(); 77 | this._navListener2.remove(); 78 | } 79 | 80 | renderHeader = () => { 81 | const { icon, name, description } = this.props.info; 82 | 83 | return ( 84 | 89 | 90 | 100 | 101 | Edit 102 | 103 | 104 | 108 | 109 | 110 | 116 | 120 | 121 | {name} 122 | 123 | 124 | {description} 125 | 126 | 127 | 128 | 129 | ); 130 | }; 131 | 132 | render() { 133 | const { email, telephone } = this.props.info; 134 | 135 | return ( 136 | 137 | {this.renderHeader()} 138 | 143 | {[ 144 | { 145 | title: 'Email address', 146 | text: email, 147 | }, 148 | { 149 | title: 'Telephone', 150 | text: telephone, 151 | }, 152 | { 153 | title: 'Notifications', 154 | custom: ( 155 | 157 | this.setState({ switch: !this.state.switch }) 158 | } 159 | value={this.state.switch} 160 | trackColor={{ false: '#ccc', true: '#d90646' }} 161 | /> 162 | ), 163 | }, 164 | { 165 | title: 'Settings', 166 | }, 167 | { 168 | title: 'Feedback', 169 | }, 170 | { 171 | title: 'Get Help', 172 | }, 173 | { 174 | title: 'Delete account', 175 | paint: true, 176 | }, 177 | ].map((item, index) => { 178 | const { title, text, custom, paint } = item; 179 | return ( 180 | 187 | ); 188 | })} 189 | 190 | 191 | ); 192 | } 193 | } 194 | 195 | Profile.defaultProps = { 196 | info: profile, 197 | }; 198 | -------------------------------------------------------------------------------- /heyU/screen/UnderConstruction.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text } from "react-native"; 3 | 4 | export default class UnderConstruction extends React.Component { 5 | render() { 6 | return ( 7 | 14 | 15 | {"Sadly, this screen is not implemented yet."} 16 | 17 | 18 | {"You can help me improve this project by forking it.\n"} 19 | 20 | 21 | {"Any help is appreciated! :)"} 22 | 23 | 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /heyU/screen/navigate.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { MaskedViewIOS, Platform, TouchableOpacity } from 'react-native'; 3 | import { 4 | createAppContainer, 5 | createBottomTabNavigator, 6 | createStackNavigator, 7 | createSwitchNavigator, 8 | } from 'react-navigation'; 9 | 10 | import { 11 | Entypo, 12 | MaterialCommunityIcons, 13 | MaterialIcons, 14 | } from '@expo/vector-icons/'; 15 | import { LinearGradient } from 'expo-linear-gradient'; 16 | 17 | import Chat from './Chat'; 18 | import Contacts from './Contacts'; 19 | import Groups from './Groups'; 20 | import Login from './Login'; 21 | import Messages from './Messages'; 22 | import Profile from './Profile'; 23 | import UnderConstruction from './UnderConstruction'; 24 | import { Block, Text } from '../components'; 25 | 26 | const firstGradientColor = '#d90646'; 27 | const secondGradientColor = '#eb402c'; 28 | 29 | const IconGradient = (props) => { 30 | if (props.iconSet === 1) { 31 | if (props.color !== firstGradientColor || Platform.OS !== 'ios') 32 | return ; 33 | 34 | return ( 35 | }> 36 | 41 | 45 | 46 | 47 | ); 48 | } else if (props.iconSet === 2) { 49 | if (props.color !== firstGradientColor || Platform.OS !== 'ios') 50 | return ; 51 | 52 | return ( 53 | }> 54 | 59 | 60 | 61 | 62 | ); 63 | } else if (props.iconSet === 3) { 64 | if (props.color !== firstGradientColor || Platform.OS !== 'ios') 65 | return ; 66 | 67 | return ( 68 | }> 69 | 74 | 75 | 76 | 77 | ); 78 | } 79 | }; 80 | 81 | const FloatingButton = (props) => { 82 | return ( 83 | 84 | 92 | 105 | 106 | + 107 | 108 | 109 | 110 | 111 | ); 112 | }; 113 | 114 | const ScreenStack = createStackNavigator( 115 | { 116 | Messages: { 117 | screen: Messages, 118 | }, 119 | Chat: { screen: Chat }, 120 | }, 121 | { 122 | initialRoute: 'Messages', 123 | } 124 | ); 125 | 126 | ScreenStack.navigationOptions = ({ navigation }) => { 127 | let tabBarVisible = true; 128 | if ( 129 | ['Chat'].includes(navigation.state.routes[navigation.state.index].routeName) 130 | ) { 131 | tabBarVisible = false; 132 | } 133 | return { 134 | tabBarVisible, 135 | }; 136 | }; 137 | 138 | const TabContainer = createBottomTabNavigator( 139 | { 140 | Stack1: { 141 | screen: ScreenStack, 142 | navigationOptions: { 143 | tabBarIcon: (tab) => ( 144 | 150 | ), 151 | }, 152 | }, 153 | Groups: { 154 | screen: Groups, 155 | navigationOptions: { 156 | tabBarIcon: (tab) => ( 157 | 163 | ), 164 | }, 165 | }, 166 | New: { 167 | screen: UnderConstruction, 168 | navigationOptions: { 169 | tabBarButtonComponent: (x) => { 170 | return ; 171 | }, 172 | }, 173 | }, 174 | Contacts: { 175 | screen: Contacts, 176 | navigationOptions: { 177 | tabBarIcon: (tab) => ( 178 | 184 | ), 185 | }, 186 | }, 187 | Profile: { 188 | screen: Profile, 189 | navigationOptions: { 190 | tabBarIcon: (tab) => ( 191 | 197 | ), 198 | }, 199 | }, 200 | }, 201 | { 202 | initialRouteName: 'Stack1', 203 | 204 | tabBarOptions: { 205 | activeTintColor: firstGradientColor, 206 | showLabel: false, 207 | style: { 208 | paddingTop: 5, 209 | paddingBottom: 10, 210 | }, 211 | }, 212 | } 213 | ); 214 | 215 | const AppContainer = createSwitchNavigator( 216 | { 217 | Login, 218 | App: TabContainer, 219 | }, 220 | { initialRouteName: 'Login' } 221 | ); 222 | 223 | export default createAppContainer(AppContainer); 224 | -------------------------------------------------------------------------------- /heyU/theme.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Image, MaskedViewIOS, Platform, Text } from 'react-native'; 3 | 4 | import { LinearGradient } from 'expo-linear-gradient'; 5 | 6 | export const colors = { 7 | primary: '#363636', 8 | secondary: '#b9b9b9', 9 | gray: '#f8f8f8', 10 | black: '#000', 11 | white: '#FFF', 12 | }; 13 | 14 | export const sizes = { 15 | // global sizes 16 | font: 14, 17 | border: 10, 18 | 19 | // font sizes 20 | title: 22, 21 | h1: 18, 22 | h2: 16, 23 | small: 12, 24 | }; 25 | 26 | export const fonts = { 27 | h1: { 28 | fontSize: sizes.h1, 29 | }, 30 | h2: { 31 | fontSize: sizes.h2, 32 | }, 33 | small: { 34 | fontSize: sizes.small, 35 | }, 36 | title: { 37 | fontSize: sizes.title, 38 | }, 39 | }; 40 | 41 | export const GradientText = (props) => { 42 | if (Platform.OS === 'ios') 43 | return ( 44 | }> 45 | 50 | 51 | 52 | 53 | ); 54 | 55 | return ; 56 | }; 57 | 58 | export const GradientIcon = (props) => { 59 | if (Platform.OS === 'ios') 60 | return ( 61 | }> 62 | 67 | 68 | 69 | 70 | ); 71 | 72 | return ; 73 | }; 74 | -------------------------------------------------------------------------------- /luxuryShop/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActivityIndicator, Image } from 'react-native'; 3 | 4 | import { Asset } from 'expo-asset'; 5 | import * as Font from 'expo-font'; 6 | 7 | import { Block } from './components'; 8 | 9 | import Navigator from './screen/navigate'; 10 | 11 | function loadIcons(images) { 12 | return images.map((image) => { 13 | if (typeof image === 'string') { 14 | return Image.prefetch(image); 15 | } else { 16 | return Asset.fromModule(image).downloadAsync(); 17 | } 18 | }); 19 | } 20 | 21 | export default class App extends React.Component { 22 | state = { 23 | iconsLoaded: false, 24 | }; 25 | 26 | async componentDidMount() { 27 | const imageAssets = loadIcons([ 28 | require('./assets/user.jpg'), 29 | require('./assets/icon.png'), 30 | require('./assets/cart.png'), 31 | require('./assets/pink-drop.png'), 32 | require('./assets/c1.jpg'), 33 | require('./assets/c2.jpg'), 34 | require('./assets/c3.jpg'), 35 | require('./assets/h1.jpg'), 36 | require('./assets/h2.jpg'), 37 | require('./assets/h3.jpg'), 38 | require('./assets/h4.jpg'), 39 | require('./assets/d1.jpg'), 40 | require('./assets/d2.jpg'), 41 | require('./assets/d3.jpg'), 42 | require('./assets/back.png'), 43 | require('./assets/top-right.png'), 44 | require('./assets/cart-white.png'), 45 | ]); 46 | 47 | await Font.loadAsync({ 48 | 'Analogue-Bold': require('./assets/fonts/Analogue55Regular.ttf'), 49 | 'Gentium-Bold': require('./assets/fonts/GenBasR.ttf'), 50 | }); 51 | 52 | await Promise.all([...imageAssets]).then(() => 53 | this.setState({ iconsLoaded: true }) 54 | ); 55 | } 56 | 57 | render() { 58 | if (!this.state.iconsLoaded) { 59 | return ( 60 | 61 | 62 | 63 | ); 64 | } 65 | 66 | return ; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /luxuryShop/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 |

7 |

8 | 9 | 10 | 11 |

12 |

13 | 14 |

15 | # Luxury Goods App 16 | 17 | built with [React Native](https://github.com/facebook/react-native) and [Expo](https://github.com/expo/expo). 18 | 19 | ## Installation 20 | 21 | - Clone this repo `git clone https://github.com/dev-andremonteiro/react-native-frontend-adventure.git` 22 | - `cd react-native-frontend-adventure` 23 | - `cd luxuryShop` 24 | - run `npm install` 25 | - run `expo start` 26 | 27 | ## Design 28 | 29 | Props to _Ray_W_ 30 | 31 | - [Dribbble](https://dribbble.com/Ray_W) 32 | 33 | Show some :heart: for the designer that made this possible 34 | 35 | ## Related SO Question 36 | 37 | [Building First Screen Image Card](https://stackoverflow.com/questions/55351050/building-image-card-in-react-native/55352500#55352500) 38 | 39 | ## Developer 40 | 41 | Andre Monteiro [dev-andremonteiro](https://github.com/dev-andremonteiro) 42 | 43 | [Follow me on Twitter](https://twitter.com/DAndremonteiro) :) 44 | -------------------------------------------------------------------------------- /luxuryShop/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Luxury Shop", 4 | "slug": "luxury-shop", 5 | "privacy": "public", 6 | "platforms": [ 7 | "ios", 8 | "android" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | }, 27 | "description": "Part of the front end advetures using React Native and Expo", 28 | "githubUrl": "https://github.com/dev-andremonteiro/react-native-frontend-adventure" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /luxuryShop/assets/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/back.png -------------------------------------------------------------------------------- /luxuryShop/assets/c1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/c1.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/c2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/c2.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/c3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/c3.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/cart-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/cart-white.png -------------------------------------------------------------------------------- /luxuryShop/assets/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/cart.png -------------------------------------------------------------------------------- /luxuryShop/assets/d1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/d1.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/d2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/d2.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/d3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/d3.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/Analogue55Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/Analogue55Regular.ttf -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/Analogue56Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/Analogue56Oblique.ttf -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/Analogue65Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/Analogue65Medium.ttf -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/GenBasB.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/GenBasB.ttf -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/GenBasR.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/GenBasR.ttf -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/Gentium-Basic.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/Gentium-Basic.zip -------------------------------------------------------------------------------- /luxuryShop/assets/fonts/analogue-12.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/fonts/analogue-12.zip -------------------------------------------------------------------------------- /luxuryShop/assets/h1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/h1.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/h2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/h2.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/h3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/h3.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/h4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/h4.jpg -------------------------------------------------------------------------------- /luxuryShop/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/icon.png -------------------------------------------------------------------------------- /luxuryShop/assets/pink-drop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/pink-drop.png -------------------------------------------------------------------------------- /luxuryShop/assets/speech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/speech.png -------------------------------------------------------------------------------- /luxuryShop/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/splash.png -------------------------------------------------------------------------------- /luxuryShop/assets/star-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/star-active.png -------------------------------------------------------------------------------- /luxuryShop/assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/star.png -------------------------------------------------------------------------------- /luxuryShop/assets/top-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/top-right.png -------------------------------------------------------------------------------- /luxuryShop/assets/user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/luxuryShop/assets/user.jpg -------------------------------------------------------------------------------- /luxuryShop/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /luxuryShop/components/Block.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { StyleSheet, View } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Block extends Component { 7 | render() { 8 | const { 9 | flex, 10 | row, 11 | column, 12 | center, 13 | middle, 14 | left, 15 | right, 16 | card, 17 | shadow, 18 | color, 19 | space, 20 | style, 21 | children, 22 | ...props 23 | } = this.props; 24 | 25 | const blockStyles = [ 26 | styles.block, 27 | flex && { flex }, 28 | flex === false && { flex: 0 }, // reset / disable flex 29 | row && styles.row, 30 | column && styles.column, 31 | center && styles.center, 32 | middle && styles.middle, 33 | left && styles.left, 34 | right && styles.right, 35 | card && styles.card, 36 | shadow && styles.shadow, 37 | space && { justifyContent: `space-${space}` }, 38 | color && styles[color], // predefined styles colors for backgroundColor 39 | color && !styles[color] && { backgroundColor: color }, // custom backgroundColor 40 | style // rewrite predefined styles 41 | ]; 42 | 43 | return ( 44 | 45 | {children} 46 | 47 | ); 48 | } 49 | } 50 | 51 | const styles = StyleSheet.create({ 52 | block: { 53 | flex: 1 54 | }, 55 | row: { 56 | flexDirection: "row" 57 | }, 58 | column: { 59 | flexDirection: "column" 60 | }, 61 | card: { 62 | borderRadius: theme.sizes.border 63 | }, 64 | center: { 65 | alignItems: "center" 66 | }, 67 | middle: { 68 | justifyContent: "center" 69 | }, 70 | left: { 71 | justifyContent: "flex-start" 72 | }, 73 | right: { 74 | justifyContent: "flex-end" 75 | }, 76 | shadow: { 77 | shadowColor: theme.colors.gray, 78 | shadowOffset: { width: 3, height: 3 }, 79 | shadowOpacity: 0.2, 80 | shadowRadius: 10 81 | }, 82 | light_gray: { backgroundColor: theme.colors.light_gray }, 83 | primary: { backgroundColor: theme.colors.primary }, 84 | black: { backgroundColor: theme.colors.black }, 85 | white: { backgroundColor: theme.colors.white }, 86 | gray: { backgroundColor: theme.colors.gray } 87 | }); 88 | -------------------------------------------------------------------------------- /luxuryShop/components/Carrousel.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Image, ScrollView } from "react-native"; 3 | 4 | import { Block } from "../components"; 5 | 6 | class Carrousel extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | this.state = { 10 | selectedCard: null 11 | }; 12 | } 13 | 14 | componentWillMount() { 15 | this.setState({ selectedCard: this.props.initalSelection }); 16 | } 17 | 18 | render() { 19 | const { 20 | style, 21 | initalSelection, 22 | imageArray, 23 | imageDimentions, 24 | spaceSeparator, 25 | selectorInactiveStyle, 26 | selectorActiveStyle, 27 | selector 28 | } = this.props; 29 | let cardWidth = imageDimentions.width + spaceSeparator; 30 | 31 | return ( 32 | 33 | { 35 | this.snapScroll = snapScroll; 36 | }} 37 | horizontal 38 | showsHorizontalScrollIndicator={false} 39 | pagingEnabled 40 | contentOffset={{ 41 | x: initalSelection * cardWidth, 42 | y: 0 43 | }} 44 | onScroll={event => { 45 | let x = event.nativeEvent.contentOffset.x; 46 | this.scrollingRight = x > this.lastX; 47 | this.lastX = x; 48 | }} 49 | onResponderRelease={() => { 50 | let snapTo = this.scrollingRight 51 | ? Math.ceil(this.lastX / cardWidth) 52 | : Math.floor(this.lastX / cardWidth); 53 | if (snapTo < 0) { 54 | this.snapScroll.scrollTo({ x: 0, y: 0 }); 55 | } else if (snapTo === imageArray.length) { 56 | this.snapScroll.scrollTo({ 57 | x: (snapTo - 1) * cardWidth, 58 | y: 0 59 | }); 60 | } else { 61 | this.setState({ selectedCard: snapTo }); 62 | 63 | let scrollTo = snapTo * cardWidth; 64 | this.snapScroll.scrollTo({ x: scrollTo, y: 0 }); 65 | } 66 | }} 67 | scrollEventThrottle={16} 68 | style={{ paddingVertical: 15 }} 69 | contentContainerStyle={{ 70 | alignItems: "flex-end" 71 | }} 72 | > 73 | {imageArray.map((item, index) => { 74 | const selected = this.state.selectedCard === index; 75 | const selectedStyle = { 76 | height: imageDimentions.height + spaceSeparator, 77 | width: imageDimentions.width + spaceSeparator 78 | }; 79 | const even = index % 2 === 0; 80 | const centerLast = index === imageArray.length - 1; 81 | const centerFirst = index === 0; 82 | 83 | return ( 84 | 94 | 95 | 96 | 101 | 102 | 103 | 104 | ); 105 | })} 106 | 107 | {selector && ( 108 | 109 | {imageArray.map((item, index) => { 110 | return ( 111 | 112 | 120 | 121 | ); 122 | })} 123 | 124 | )} 125 | 126 | ); 127 | } 128 | } 129 | 130 | Carrousel.defaultProps = { 131 | initalSelection: 0, 132 | spaceSeparator: 20, 133 | selectorInactiveStyle: { 134 | width: 6, 135 | height: 6, 136 | borderRadius: 3, 137 | margin: 3, 138 | backgroundColor: "#000", 139 | opacity: 0.2 140 | }, 141 | selectorActiveStyle: { 142 | width: 6, 143 | height: 6, 144 | borderRadius: 3, 145 | margin: 3, 146 | backgroundColor: "#000" 147 | }, 148 | selector: true 149 | }; 150 | 151 | export default Carrousel; 152 | -------------------------------------------------------------------------------- /luxuryShop/components/Text.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Text, StyleSheet } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Typography extends Component { 7 | render() { 8 | const { 9 | title, 10 | h1, 11 | h2, 12 | caption, 13 | small, 14 | size, 15 | // styling 16 | bold, 17 | semibold, 18 | light, 19 | center, 20 | right, 21 | // colors 22 | color, 23 | primary, 24 | black, 25 | white, 26 | gray, 27 | light_gray, 28 | style, 29 | children, 30 | ...props 31 | } = this.props; 32 | 33 | const textStyles = [ 34 | styles.text, 35 | title && styles.title, 36 | h1 && styles.h1, 37 | h2 && styles.h2, 38 | caption && styles.caption, 39 | small && styles.small, 40 | size && { fontSize: size }, 41 | bold && styles.bold, 42 | semibold && styles.semibold, 43 | light && styles.light, 44 | center && styles.center, 45 | right && styles.right, 46 | color && styles[color], 47 | color && !styles[color] && { color }, 48 | // color shortcuts 49 | primary && styles.primary, 50 | black && styles.black, 51 | white && styles.white, 52 | gray && styles.gray, 53 | light_gray && styles.light_gray, 54 | style // rewrite predefined styles 55 | ]; 56 | 57 | return ( 58 | 59 | {children} 60 | 61 | ); 62 | } 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | // default style 67 | text: { 68 | fontFamily: "Gentium-Bold", 69 | fontSize: theme.sizes.font, 70 | color: theme.colors.black 71 | }, 72 | // variations 73 | bold: { 74 | fontWeight: "bold" 75 | }, 76 | semibold: { 77 | fontWeight: "500" 78 | }, 79 | light: { 80 | fontWeight: "200" 81 | }, 82 | // position 83 | center: { textAlign: "center" }, 84 | right: { textAlign: "right" }, 85 | // colors 86 | light_gray: { color: theme.colors.light_gray }, 87 | primary: { color: theme.colors.primary }, 88 | black: { color: theme.colors.black }, 89 | white: { color: theme.colors.white }, 90 | gray: { color: theme.colors.gray }, 91 | // fonts 92 | title: theme.fonts.title, 93 | h1: theme.fonts.h1, 94 | h2: theme.fonts.h2, 95 | caption: theme.fonts.caption, 96 | small: theme.fonts.small 97 | }); 98 | -------------------------------------------------------------------------------- /luxuryShop/components/index.js: -------------------------------------------------------------------------------- 1 | import Block from './Block'; 2 | import Text from './Text'; 3 | 4 | export { Block, Text }; -------------------------------------------------------------------------------- /luxuryShop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "eject": "expo eject" 8 | }, 9 | "dependencies": { 10 | "expo": "^40.0.0", 11 | "expo-asset": "~8.2.1", 12 | "expo-font": "~8.4.0", 13 | "expo-linear-gradient": "~8.4.0", 14 | "react": "16.13.1", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz", 16 | "react-native-gesture-handler": "~1.8.0", 17 | "react-native-screens": "~2.15.2", 18 | "react-navigation": "^3.3.2" 19 | }, 20 | "devDependencies": { 21 | "babel-preset-expo": "8.3.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /luxuryShop/screen/Home/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | Image, 6 | ScrollView, 7 | TouchableOpacity 8 | } from "react-native"; 9 | 10 | import { Block, Text } from "../../components"; 11 | import * as theme from "../../theme"; 12 | 13 | class Home extends React.Component { 14 | static navigationOptions = ({ navigation }) => { 15 | return { 16 | header: ( 17 | 18 | 28 | 32 | 36 | 40 | 41 | 42 | ) 43 | }; 44 | }; 45 | 46 | changeScreen = () => this.props.navigation.navigate("Product"); 47 | 48 | renderSectionHeader(title) { 49 | return ( 50 | 56 | 60 | 61 | {title} 62 | 63 | 64 | 69 | 70 | 79 | View all 80 | 81 | 82 | ); 83 | } 84 | 85 | renderCategories() { 86 | const { categories } = this.props; 87 | 88 | return ( 89 | 97 | {categories.map((item, index) => { 98 | const { name, image } = item; 99 | 100 | return ( 101 | 102 | 103 | 111 | 112 | 113 | 114 | {name} 115 | 116 | 117 | 118 | ); 119 | })} 120 | 121 | ); 122 | } 123 | 124 | renderSelectedCat() { 125 | const { products } = this.props; 126 | let duplicate = [...products]; 127 | let secondHalf = duplicate.splice(duplicate.length / 2); 128 | 129 | return ( 130 | 134 | 135 | {[duplicate, secondHalf].map((item, index) => { 136 | let halfCards = item.map((item2, index2) => { 137 | const { name, pop, fav, image } = item2; 138 | const leftColumn = index === 0; 139 | const favIcon = fav 140 | ? require("../../assets/star-active.png") 141 | : require("../../assets/star.png"); 142 | 143 | return ( 144 | 148 | 149 | 150 | 154 | 155 | 156 | 163 | 164 | 165 | {name} 166 | 167 | 168 | {pop} 169 | 170 | 171 | 178 | 182 | 183 | 184 | 185 | 186 | 187 | ); 188 | }); 189 | 190 | return ( 191 | 196 | {halfCards} 197 | 198 | ); 199 | })} 200 | 201 | 202 | ); 203 | } 204 | 205 | render() { 206 | return ( 207 | 208 | 209 | {this.renderSectionHeader("All Product")} 210 | {this.renderCategories()} 211 | 212 | 213 | {this.renderSectionHeader("Spring clothing")} 214 | {this.renderSelectedCat()} 215 | 216 | 217 | ); 218 | } 219 | } 220 | 221 | Home.defaultProps = { 222 | categories: [ 223 | { name: "Sweater", image: require("../../assets/c1.jpg") }, 224 | { name: "Spring clothing", image: require("../../assets/c2.jpg") }, 225 | { name: "A suit", image: require("../../assets/c3.jpg") } 226 | ], 227 | products: [ 228 | { 229 | name: "Tide product", 230 | pop: "6.89+popularity", 231 | fav: false, 232 | image: require("../../assets/h1.jpg") 233 | }, 234 | { 235 | name: "Small and pure", 236 | pop: "hot last week", 237 | fav: false, 238 | image: require("../../assets/h2.jpg") 239 | }, 240 | { 241 | name: "Have a good ", 242 | pop: "6.89+popularity", 243 | fav: true, 244 | image: require("../../assets/h3.jpg") 245 | }, 246 | { 247 | name: "Glamurous", 248 | pop: "best deal", 249 | fav: false, 250 | image: require("../../assets/h4.jpg") 251 | } 252 | ] 253 | }; 254 | 255 | export default Home; 256 | 257 | const styles = StyleSheet.create({ 258 | safe: { 259 | backgroundColor: theme.colors.white 260 | } 261 | }); 262 | -------------------------------------------------------------------------------- /luxuryShop/screen/Product/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | SafeAreaView, 4 | StyleSheet, 5 | Image, 6 | TouchableOpacity 7 | } from "react-native"; 8 | 9 | import { Block, Text } from "../../components"; 10 | import * as theme from "../../theme"; 11 | import Carrousel from "../../components/Carrousel"; 12 | 13 | class Product extends React.Component { 14 | static navigationOptions = ({ navigation }) => { 15 | return { 16 | header: ( 17 | 18 | 19 | navigation.goBack()} 26 | > 27 | 31 | 32 | 33 | 34 | Details 35 | 36 | 37 | 38 | 44 | 48 | 49 | 50 | 51 | ) 52 | }; 53 | }; 54 | 55 | renderPhotoViewer() { 56 | const { product } = this.props; 57 | const { photos } = product; 58 | 59 | return ( 60 | 81 | ); 82 | } 83 | 84 | renderInfoCard() { 85 | const { product } = this.props; 86 | const { title, price, subtitle, desc } = product; 87 | 88 | let firstDigit = price.toString().slice(0, 1); 89 | 90 | return ( 91 | 102 | 103 | 104 | {title} 105 | 106 | 107 | 108 | {"$"} 109 | 110 | 111 | {firstDigit} 112 | 113 | 114 | {price.toString().slice(1)} 115 | 116 | 117 | 118 | 119 | 120 | {subtitle} 121 | 122 | 123 | {desc} 124 | 125 | 126 | 127 | ); 128 | } 129 | 130 | renderButtons() { 131 | return ( 132 | 138 | 147 | 156 | 160 | 161 | 168 | 172 | 173 | 174 | 175 | 185 | 190 | 195 | {"ADD TO CART"} 196 | 197 | 198 | 199 | ); 200 | } 201 | 202 | render() { 203 | return ( 204 | 205 | {this.renderPhotoViewer()} 206 | {this.renderInfoCard()} 207 | {this.renderButtons()} 208 | 209 | ); 210 | } 211 | } 212 | 213 | Product.defaultProps = { 214 | product: { 215 | photos: [ 216 | require("../../assets/d1.jpg"), 217 | require("../../assets/d2.jpg"), 218 | require("../../assets/d3.jpg") 219 | ], 220 | title: "Spring with lotus", 221 | price: 199, 222 | subtitle: "Model is 5'11 and wearing size Small", 223 | desc: 224 | "This essential t-shirt dress features V-neck and a relaxed fit for an effortless look that's ready to style" 225 | } 226 | }; 227 | 228 | export default Product; 229 | 230 | const styles = StyleSheet.create({ 231 | safe: { 232 | backgroundColor: theme.colors.white 233 | } 234 | }); 235 | -------------------------------------------------------------------------------- /luxuryShop/screen/navigate.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createStackNavigator, createAppContainer } from "react-navigation"; 3 | 4 | import Home from "./Home"; 5 | import Product from "./Product"; 6 | 7 | export default createAppContainer( 8 | createStackNavigator( 9 | { 10 | Home, 11 | Product 12 | }, 13 | { 14 | initialRouteName: "Home" 15 | } 16 | ) 17 | ); 18 | -------------------------------------------------------------------------------- /luxuryShop/theme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | primary: "#FF5C72", 3 | black: "#000", 4 | white: "#FFF", 5 | light_gray: "#eee", 6 | gray: "#666" 7 | }; 8 | 9 | const sizes = { 10 | // global sizes 11 | font: 12, 12 | border: 5, 13 | 14 | // font sizes 15 | title: 20, 16 | h1: 18, 17 | h2: 16, 18 | small: 12, 19 | caption: 8 20 | }; 21 | 22 | const fonts = { 23 | title: { 24 | fontSize: sizes.title 25 | }, 26 | h1: { 27 | fontSize: sizes.h1 28 | }, 29 | h2: { 30 | fontSize: sizes.h2 31 | }, 32 | small: { 33 | fontSize: sizes.small 34 | }, 35 | caption: { 36 | fontSize: sizes.caption 37 | } 38 | }; 39 | 40 | export { colors, sizes, fonts }; 41 | -------------------------------------------------------------------------------- /triviaAlt/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Image, 4 | ImageBackground, 5 | SafeAreaView, 6 | ScrollView, 7 | StatusBar, 8 | StyleSheet, 9 | } from 'react-native'; 10 | 11 | import { Asset } from 'expo-asset'; 12 | 13 | import { Block, Text } from './components'; 14 | import * as theme from './theme'; 15 | 16 | class App extends React.Component { 17 | state = { 18 | iconsLoaded: false, 19 | selectedCard: 0, 20 | }; 21 | 22 | loadIcons(images) { 23 | return images.map((image) => { 24 | if (typeof image === 'string') { 25 | return Image.prefetch(image); 26 | } else { 27 | return Asset.fromModule(image).downloadAsync(); 28 | } 29 | }); 30 | } 31 | 32 | async componentDidMount() { 33 | const imageAssets = this.loadIcons([ 34 | require('./assets/back.png'), 35 | require('./assets/collapse.png'), 36 | require('./assets/fire.png'), 37 | require('./assets/fire-active.png'), 38 | require('./assets/light.png'), 39 | require('./assets/light-active.png'), 40 | require('./assets/ranking.png'), 41 | require('./assets/star.png'), 42 | require('./assets/star-active.png'), 43 | require('./assets/top-left.png'), 44 | require('./assets/top-right.png'), 45 | ]); 46 | await Promise.all([...imageAssets]).then(() => 47 | this.setState({ iconsLoaded: true }) 48 | ); 49 | } 50 | 51 | renderHeader() { 52 | let { user } = this.props; 53 | 54 | return ( 55 | 63 | 67 | 68 | 69 | WELCOME 70 | 71 | 72 | {user} 73 | 74 | 75 | 79 | 80 | ); 81 | } 82 | 83 | renderCards() { 84 | const { status } = this.props; 85 | const { selectedCard } = this.state; 86 | 87 | return ( 88 | { 93 | let x = event.nativeEvent.contentOffset.x; 94 | if (x < 0 || x > 310) return; 95 | if (x >= 80) 96 | this.setState({ selectedCard: Math.floor((x - 80) / 170) + 1 }); 97 | else this.setState({ selectedCard: 0 }); 98 | }} 99 | scrollEventThrottle={16} 100 | > 101 | 105 | 113 | 114 | {status.rank.toString()} 115 | 116 | 117 | 118 | Your rank 119 | 120 | 129 | Between 5,346 Users 130 | 131 | 132 | 133 | 134 | 138 | 146 | 147 | {status.answers.toString() + '%'} 148 | 149 | 150 | 151 | Correct Answers 152 | 153 | 162 | At your first attempt 163 | 164 | 165 | 166 | 167 | 171 | 179 | 180 | {status.score.toString()} 181 | 182 | 183 | 184 | Your Score 185 | 186 | 195 | After two weeks 196 | 197 | 198 | 199 | 204 | 208 | 209 | 210 | Go to Leaderboard 211 | 212 | 213 | 214 | 215 | ); 216 | } 217 | 218 | renderFooter() { 219 | return ( 220 | 230 | 234 | 235 | Week 2 236 | 237 | 238 | ); 239 | } 240 | 241 | render() { 242 | if (!this.state.iconsLoaded) { 243 | return ( 244 | 245 | Loading 246 | 247 | ); 248 | } 249 | 250 | return ( 251 | 255 | 256 | 257 | {this.renderHeader()} 258 | {this.renderCards()} 259 | {this.renderFooter()} 260 | 261 | 262 | ); 263 | } 264 | } 265 | 266 | App.defaultProps = { 267 | user: 'Michael S.', 268 | status: { 269 | rank: 384, 270 | answers: 45, 271 | score: 3.684, 272 | }, 273 | week: 2, 274 | }; 275 | 276 | export default App; 277 | 278 | const styles = StyleSheet.create({ 279 | safe: { 280 | flex: 1, 281 | }, 282 | header: { 283 | paddingTop: 30, 284 | paddingBottom: 55, 285 | paddingHorizontal: 20, 286 | }, 287 | scroll: { 288 | paddingLeft: 20, 289 | }, 290 | card: { 291 | width: 150, 292 | height: 300, 293 | paddingHorizontal: 20, 294 | paddingVertical: 40, 295 | borderRadius: 10, 296 | marginHorizontal: 5, 297 | borderColor: theme.colors.gray, 298 | borderWidth: 1, 299 | }, 300 | rank: { 301 | height: 340, 302 | borderWidth: 0, 303 | backgroundColor: theme.colors.rank, 304 | }, 305 | stats: { 306 | height: 340, 307 | borderWidth: 0, 308 | backgroundColor: theme.colors.stats, 309 | }, 310 | score: { 311 | height: 340, 312 | borderWidth: 0, 313 | backgroundColor: theme.colors.score, 314 | }, 315 | topIcon: { 316 | height: 32, 317 | width: 32, 318 | }, 319 | cardIcon: { 320 | height: 22, 321 | width: 22, 322 | }, 323 | }); 324 | -------------------------------------------------------------------------------- /triviaAlt/README.md: -------------------------------------------------------------------------------- 1 |

2 | react-native-fancy-drawer 3 | react-native-fancy-drawer 4 |

5 | 6 |

7 | 8 | 9 | 10 |

11 | 12 |

13 | 14 |

15 | 16 | # Trivia Alternative Style 17 | 18 | built with [React Native](https://github.com/facebook/react-native) and [Expo](https://github.com/expo/expo). 19 | 20 | ## Installation 21 | 22 | - Clone this repo `git clone https://github.com/dev-andremonteiro/react-native-frontend-adventure.git` 23 | - `cd react-native-frontend-adventure` 24 | - `cd triviaAlt` 25 | - run `npm install` 26 | - run `expo start` 27 | 28 | ## Design 29 | 30 | All props to guys at [misto Team](http://misto.co/) 31 | 32 | - [Dribbble](https://dribbble.com/mistodotco) 33 | 34 | - [Instagram](https://dribbble.com/mistodotco/click?type=instagram) 35 | 36 | Show some :heart: for designers that made this possible 37 | 38 | 39 | 40 | ## Developer 41 | 42 | André Monteiro [dev-andremonteiro](https://github.com/dev-andremonteiro) 43 | 44 | [Follow me on Twitter](https://twitter.com/DAndremonteiro) :) 45 | -------------------------------------------------------------------------------- /triviaAlt/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Trivia Alternative", 4 | "slug": "trivia-alternative", 5 | "privacy": "public", 6 | "platforms": [ 7 | "ios", 8 | "android" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | }, 27 | "description": "Part of the front end advetures using React Native and Expo", 28 | "githubUrl": "https://github.com/dev-andremonteiro/react-native-frontend-adventure" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /triviaAlt/assets/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/back.png -------------------------------------------------------------------------------- /triviaAlt/assets/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/collapse.png -------------------------------------------------------------------------------- /triviaAlt/assets/fire-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/fire-active.png -------------------------------------------------------------------------------- /triviaAlt/assets/fire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/fire.png -------------------------------------------------------------------------------- /triviaAlt/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/icon.png -------------------------------------------------------------------------------- /triviaAlt/assets/light-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/light-active.png -------------------------------------------------------------------------------- /triviaAlt/assets/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/light.png -------------------------------------------------------------------------------- /triviaAlt/assets/ranking-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/ranking-active.png -------------------------------------------------------------------------------- /triviaAlt/assets/ranking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/ranking.png -------------------------------------------------------------------------------- /triviaAlt/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/splash.png -------------------------------------------------------------------------------- /triviaAlt/assets/star-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/star-active.png -------------------------------------------------------------------------------- /triviaAlt/assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/star.png -------------------------------------------------------------------------------- /triviaAlt/assets/top-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/top-left.png -------------------------------------------------------------------------------- /triviaAlt/assets/top-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-andremonteiro/react-native-frontend-adventure/1187d824b65b1bcfe374713a2b356e780abb6de7/triviaAlt/assets/top-right.png -------------------------------------------------------------------------------- /triviaAlt/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /triviaAlt/components/Block.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { StyleSheet, View } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Block extends Component { 7 | render() { 8 | const { 9 | flex, 10 | row, 11 | column, 12 | center, 13 | middle, 14 | left, 15 | right, 16 | card, 17 | shadow, 18 | color, 19 | space, 20 | style, 21 | children, 22 | ...props 23 | } = this.props; 24 | 25 | const blockStyles = [ 26 | styles.block, 27 | flex && { flex }, 28 | flex === false && { flex: 0 }, // reset / disable flex 29 | row && styles.row, 30 | column && styles.column, 31 | center && styles.center, 32 | middle && styles.middle, 33 | left && styles.left, 34 | right && styles.right, 35 | card && styles.card, 36 | shadow && styles.shadow, 37 | space && { justifyContent: `space-${space}` }, 38 | color && styles[color], // predefined styles colors for backgroundColor 39 | color && !styles[color] && { backgroundColor: color }, // custom backgroundColor 40 | style // rewrite predefined styles 41 | ]; 42 | 43 | return ( 44 | 45 | {children} 46 | 47 | ); 48 | } 49 | } 50 | 51 | const styles = StyleSheet.create({ 52 | block: { 53 | flex: 1 54 | }, 55 | row: { 56 | flexDirection: "row" 57 | }, 58 | column: { 59 | flexDirection: "column" 60 | }, 61 | card: { 62 | borderRadius: theme.sizes.border 63 | }, 64 | center: { 65 | alignItems: "center" 66 | }, 67 | middle: { 68 | justifyContent: "center" 69 | }, 70 | left: { 71 | justifyContent: "flex-start" 72 | }, 73 | right: { 74 | justifyContent: "flex-end" 75 | }, 76 | shadow: { 77 | shadowColor: theme.colors.black, 78 | shadowOffset: { width: 0, height: 4 }, 79 | shadowOpacity: 0.1, 80 | shadowRadius: 10 81 | }, 82 | rank: { backgroundColor: theme.colors.rank }, 83 | stats: { backgroundColor: theme.colors.stats }, 84 | score: { backgroundColor: theme.colors.score }, 85 | primary: { backgroundColor: theme.colors.primary }, 86 | secondary: { backgroundColor: theme.colors.secondary }, 87 | leader: { backgroundColor: theme.colors.leader }, 88 | black: { backgroundColor: theme.colors.black }, 89 | white: { backgroundColor: theme.colors.white }, 90 | gray: { backgroundColor: theme.colors.gray } 91 | }); 92 | -------------------------------------------------------------------------------- /triviaAlt/components/Text.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Text, StyleSheet } from "react-native"; 3 | 4 | import * as theme from "../theme"; 5 | 6 | export default class Typography extends Component { 7 | render() { 8 | const { 9 | title, 10 | footer, 11 | caption, 12 | small, 13 | subtitle, 14 | size, 15 | // styling 16 | bold, 17 | semibold, 18 | light, 19 | center, 20 | right, 21 | // colors 22 | color, 23 | leader, 24 | primary, 25 | secondary, 26 | black, 27 | white, 28 | gray, 29 | rank, 30 | stats, 31 | score, 32 | style, 33 | children, 34 | ...props 35 | } = this.props; 36 | 37 | const textStyles = [ 38 | styles.text, 39 | title && styles.title, 40 | footer && styles.footer, 41 | caption && styles.caption, 42 | small && styles.small, 43 | size && { fontSize: size }, 44 | bold && styles.bold, 45 | semibold && styles.semibold, 46 | light && styles.light, 47 | center && styles.center, 48 | right && styles.right, 49 | color && styles[color], 50 | color && !styles[color] && { color }, 51 | // color shortcuts 52 | leader && styles.leader, 53 | primary && styles.primary, 54 | secondary && styles.secondary, 55 | black && styles.black, 56 | white && styles.white, 57 | gray && styles.gray, 58 | rank && styles.rank, 59 | stats && styles.stats, 60 | score && styles.score, 61 | style // rewrite predefined styles 62 | ]; 63 | 64 | return ( 65 | 66 | {children} 67 | 68 | ); 69 | } 70 | } 71 | 72 | const styles = StyleSheet.create({ 73 | // default style 74 | text: { 75 | // fontFamily: "Montserrat-Regular", 76 | fontSize: theme.sizes.font, 77 | color: theme.colors.black 78 | }, 79 | // variations 80 | bold: { 81 | fontWeight: "bold" 82 | }, 83 | semibold: { 84 | fontWeight: "500" 85 | }, 86 | light: { 87 | fontWeight: "200" 88 | }, 89 | // position 90 | center: { textAlign: "center" }, 91 | right: { textAlign: "right" }, 92 | // colors 93 | rank: { color: theme.colors.rank }, 94 | stats: { color: theme.colors.stats }, 95 | score: { color: theme.colors.score }, 96 | primary: { color: theme.colors.primary }, 97 | secondary: { color: theme.colors.secondary }, 98 | leader: { color: theme.colors.leader }, 99 | black: { color: theme.colors.black }, 100 | white: { color: theme.colors.white }, 101 | gray: { color: theme.colors.gray }, 102 | // fonts 103 | title: theme.fonts.title, 104 | footer: theme.fonts.footer, 105 | caption: theme.fonts.caption, 106 | small: theme.fonts.small 107 | }); 108 | -------------------------------------------------------------------------------- /triviaAlt/components/index.js: -------------------------------------------------------------------------------- 1 | import Block from './Block'; 2 | import Text from './Text'; 3 | 4 | export { Block, Text }; -------------------------------------------------------------------------------- /triviaAlt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "eject": "expo eject" 8 | }, 9 | "dependencies": { 10 | "expo": "^40.0.0", 11 | "expo-asset": "~8.2.1", 12 | "expo-font": "~8.4.0", 13 | "expo-linear-gradient": "~8.4.0", 14 | "react": "16.13.1", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz", 16 | "react-native-gesture-handler": "~1.8.0", 17 | "react-native-screens": "~2.15.2" 18 | }, 19 | "devDependencies": { 20 | "babel-preset-expo": "8.3.0" 21 | }, 22 | "private": true 23 | } 24 | -------------------------------------------------------------------------------- /triviaAlt/theme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | primary: "#1A2A3B", 3 | secondary: "#03E0F4", 4 | leader: "#2e425a", 5 | rank: "#1AB2D2", 6 | stats: "#19d3a5", 7 | score: "#D34819", 8 | black: "#000000", 9 | white: "#FFFFFF", 10 | light_white: "rgba(255,255,255,0.5)", 11 | gray: "#5C6776" 12 | }; 13 | 14 | const sizes = { 15 | // global sizes 16 | font: 12, 17 | border: 10, 18 | 19 | // font sizes 20 | title: 32, 21 | caption: 12, 22 | small: 10, 23 | footer: 20 24 | }; 25 | 26 | const fonts = { 27 | title: { 28 | fontSize: sizes.title 29 | }, 30 | body: { 31 | fontSize: sizes.body 32 | }, 33 | caption: { 34 | fontSize: sizes.caption 35 | }, 36 | small: { 37 | fontSize: sizes.small 38 | }, 39 | footer: { 40 | fontSize: sizes.footer 41 | } 42 | }; 43 | 44 | export { colors, sizes, fonts }; 45 | --------------------------------------------------------------------------------