summaryrefslogtreecommitdiff
path: root/frontend/app/screens
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2019-03-11 21:00:02 +0400
committerAndrew <saintruler@gmail.com>2019-03-11 21:00:02 +0400
commit7e7dd5244e8d26485ad7950a89c04c98c4fef83f (patch)
tree810730c4650392080fb87a78d3b527201e89fe4b /frontend/app/screens
Initial commit/
Diffstat (limited to 'frontend/app/screens')
-rw-r--r--frontend/app/screens/articles/article.js94
-rw-r--r--frontend/app/screens/articles/articles1.js74
-rw-r--r--frontend/app/screens/articles/articles2.js84
-rw-r--r--frontend/app/screens/articles/articles3.js81
-rw-r--r--frontend/app/screens/articles/articles4.js78
-rw-r--r--frontend/app/screens/articles/blogposts.js88
-rw-r--r--frontend/app/screens/articles/index.js6
-rw-r--r--frontend/app/screens/dashboard/dashboard.js117
-rw-r--r--frontend/app/screens/dashboard/index.js1
-rw-r--r--frontend/app/screens/eCommerce/addToCardForm.js138
-rw-r--r--frontend/app/screens/eCommerce/cards.js242
-rw-r--r--frontend/app/screens/eCommerce/index.js2
-rw-r--r--frontend/app/screens/index.js11
-rw-r--r--frontend/app/screens/login/index.js4
-rw-r--r--frontend/app/screens/login/login1.js129
-rw-r--r--frontend/app/screens/login/login2.js127
-rw-r--r--frontend/app/screens/login/passwordRecovery.js83
-rw-r--r--frontend/app/screens/login/signUp.js110
-rw-r--r--frontend/app/screens/menu/categoryMenu.js77
-rw-r--r--frontend/app/screens/menu/index.js2
-rw-r--r--frontend/app/screens/menu/menus.js114
-rw-r--r--frontend/app/screens/messaging/chat.js214
-rw-r--r--frontend/app/screens/messaging/chatList.js147
-rw-r--r--frontend/app/screens/messaging/comments.js98
-rw-r--r--frontend/app/screens/messaging/index.js3
-rw-r--r--frontend/app/screens/navigation/grid.js70
-rw-r--r--frontend/app/screens/navigation/grid2.js82
-rw-r--r--frontend/app/screens/navigation/index.js4
-rw-r--r--frontend/app/screens/navigation/list.js73
-rw-r--r--frontend/app/screens/navigation/sideMenu.js113
-rw-r--r--frontend/app/screens/other/index.js2
-rw-r--r--frontend/app/screens/other/settings.js176
-rw-r--r--frontend/app/screens/other/splash.js108
-rw-r--r--frontend/app/screens/social/contacts.js124
-rw-r--r--frontend/app/screens/social/feed.js73
-rw-r--r--frontend/app/screens/social/index.js7
-rw-r--r--frontend/app/screens/social/notifications.js98
-rw-r--r--frontend/app/screens/social/profile1.js104
-rw-r--r--frontend/app/screens/social/profile2.js108
-rw-r--r--frontend/app/screens/social/profile3.js96
-rw-r--r--frontend/app/screens/social/profileSettings.js200
-rw-r--r--frontend/app/screens/theme/index.js1
-rw-r--r--frontend/app/screens/theme/themes.js77
-rw-r--r--frontend/app/screens/walkthroughs/index.js1
-rw-r--r--frontend/app/screens/walkthroughs/walkthrough1.js40
-rw-r--r--frontend/app/screens/walkthroughs/walkthrough2.js46
-rw-r--r--frontend/app/screens/walkthroughs/walkthroughScreen.js61
47 files changed, 3788 insertions, 0 deletions
diff --git a/frontend/app/screens/articles/article.js b/frontend/app/screens/articles/article.js
new file mode 100644
index 0000000..059ab44
--- /dev/null
+++ b/frontend/app/screens/articles/article.js
@@ -0,0 +1,94 @@
+import React from 'react';
+import axios from 'axios';
+
+
+import {
+ ScrollView,
+ Image,
+ View,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkCard,
+ RkText,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import {
+ Avatar,
+ SocialBar,
+} from '../../components';
+import NavigationType from '../../config/navigation/propTypes';
+
+
+export class Article extends React.Component {
+ state = {
+ article: {},
+ mounted: false,
+ };
+
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Current problem'.toUpperCase(),
+ };
+
+
+ componentWillMount() {
+ const articleId = this.props.navigation.getParam('id', 1);
+ console.log(articleId);
+
+ axios.get(`http://192.168.1.43:8000/api/articles/${articleId}`)
+ .then(res => {
+ this.setState({
+ article: res.data,
+ mounted: true,
+ });
+ console.log(this.state.article);
+ });
+ }
+
+ render() {
+ if (this.state.mounted) {
+ return (
+ <ScrollView style={styles.root}>
+ <RkCard rkType='article'>
+ <Image
+ rkCardImg
+ source={{
+ uri: `${this.state.article.image.toString()
+ .replace('http://127.0.0.1:8000/', '')}`,
+ }}
+ />
+ <View rkCardHeader>
+ <View>
+ <RkText style={styles.title} rkType='header4'>{this.state.article.title}</RkText>
+ </View>
+
+
+ </View>
+ <View rkCardContent>
+ <View>
+ <RkText rkType='primary3 bigLine'>{this.state.article.text}</RkText>
+ </View>
+ </View>
+ <View rkCardFooter>
+ <SocialBar comments={this.state.article.n_comments} is_solved={this.state.article.is_solved ? 'Solved' : "Doesn't solved"}/>
+ </View>
+ </RkCard>
+ </ScrollView>
+
+ );
+ }
+ return null;
+ }
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ title: {
+ marginBottom: 5,
+ },
+}));
diff --git a/frontend/app/screens/articles/articles1.js b/frontend/app/screens/articles/articles1.js
new file mode 100644
index 0000000..47049b4
--- /dev/null
+++ b/frontend/app/screens/articles/articles1.js
@@ -0,0 +1,74 @@
+import React from 'react';
+import {
+ FlatList,
+ Image,
+ View,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkText,
+ RkCard, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { SocialBar } from '../../components';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class Articles1 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Article List'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getArticles(),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onItemPressed = ({ item }) => {
+ this.props.navigation.navigate('Article', { id: item.id });
+ };
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={() => this.onItemPressed(item)}>
+ <RkCard rkType='backImg'>
+ <Image rkCardImg source={item.photo} />
+ <View rkCardImgOverlay rkCardContent style={styles.overlay}>
+ <RkText rkType='header2 inverseColor'>{item.header}</RkText>
+ <RkText rkType='secondary2 inverseColor'>{moment().add(item.time, 'seconds').fromNow()}</RkText>
+ <View rkCardFooter style={styles.footer}>
+ <SocialBar rkType='leftAligned' />
+ </View >
+ </View>
+ </RkCard>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <FlatList
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.root}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ overlay: {
+ justifyContent: 'flex-end',
+ },
+ footer: {
+ width: 240,
+ },
+}));
diff --git a/frontend/app/screens/articles/articles2.js b/frontend/app/screens/articles/articles2.js
new file mode 100644
index 0000000..0d48812
--- /dev/null
+++ b/frontend/app/screens/articles/articles2.js
@@ -0,0 +1,84 @@
+import React from 'react';
+import {
+ FlatList,
+ Image,
+ View,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkText,
+ RkCard, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import axios from 'axios';
+import { SocialBar } from '../../components';
+import NavigationType from '../../config/navigation/propTypes';
+
+
+export class Articles2 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Problems List'.toUpperCase(),
+ };
+
+ state = {
+ articles: [],
+ };
+
+ componentDidMount() {
+ axios.get('http://192.168.1.43:8000/api/articles')
+ .then(res => {
+ this.setState({
+ articles: res.data,
+ });
+
+ });
+ }
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate('Article', { id: item.id });
+ };
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={() => this.onItemPressed(item)}>
+ <RkCard rkType='imgBlock' style={styles.card}>
+ <Image rkCardImg source={{ uri: `${item.image.toString().replace('http://127.0.0.1:8000/', '')}` }} />
+ <View rkCardImgOverlay rkCardContent style={styles.overlay}>
+ <RkText rkType='header4 inverseColor'>{item.title}</RkText>
+ </View>
+ <View rkCardFooter>
+ <SocialBar rkType='space' showLabel likes={item.rating} comments={item.n_comments} is_solved={item.is_solved ? 'Solved' : "Doesn't solved"} />
+ </View>
+ </RkCard>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <FlatList
+ data={this.state.articles}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.container}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingVertical: 8,
+ paddingHorizontal: 14,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ time: {
+ marginTop: 5,
+ },
+}));
diff --git a/frontend/app/screens/articles/articles3.js b/frontend/app/screens/articles/articles3.js
new file mode 100644
index 0000000..e5eda4e
--- /dev/null
+++ b/frontend/app/screens/articles/articles3.js
@@ -0,0 +1,81 @@
+import React from 'react';
+import {
+ FlatList,
+ Image,
+ View,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkText,
+ RkCard, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { SocialBar } from '../../components';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class Articles3 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Article List'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getArticles(),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onItemPressed = ({ item }) => {
+ this.props.navigation.navigate('Article', { id: item.id });
+ };
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={() => this.onItemPressed(item)}>
+ <RkCard style={styles.card}>
+ <View rkCardHeader>
+ <View>
+ <RkText rkType='header4'>{item.header}</RkText>
+ <RkText rkType='secondary2 hintColor'>{moment().add(item.time, 'seconds').fromNow()}</RkText>
+ </View>
+ </View>
+ <Image rkCardImg source={item.photo} />
+ <View style={styles.footer} rkCardFooter>
+ <SocialBar />
+ </View >
+ </RkCard>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <FlatList
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.container}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingHorizontal: 14,
+ paddingVertical: 8,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ footer: {
+ paddingTop: 16,
+ },
+ time: {
+ marginTop: 5,
+ },
+}));
diff --git a/frontend/app/screens/articles/articles4.js b/frontend/app/screens/articles/articles4.js
new file mode 100644
index 0000000..1f08ba1
--- /dev/null
+++ b/frontend/app/screens/articles/articles4.js
@@ -0,0 +1,78 @@
+import React from 'react';
+import {
+ FlatList,
+ Image,
+ View,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkText,
+ RkCard,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { SocialBar } from '../../components';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+
+export class Articles4 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Article List'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getArticles(),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={() => this.props.navigation.navigate('Article', { id: item.id })}>
+ <RkCard rkType='horizontal' style={styles.card}>
+ <Image rkCardImg source={item.photo} />
+ <View rkCardContent>
+ <RkText numberOfLines={1} rkType='header6'>{item.header}</RkText>
+ <RkText rkType='secondary6 hintColor'>
+ {`${item.user.firstName} ${item.user.lastName}`}
+ </RkText>
+ <RkText style={styles.post} numberOfLines={2} rkType='secondary1'>{item.text}</RkText>
+ </View>
+ <View rkCardFooter>
+ <SocialBar rkType='space' showLabel />
+ </View >
+ </RkCard>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <View>
+ <FlatList
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.container}
+ />
+ </View>
+ );
+}
+
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingVertical: 8,
+ paddingHorizontal: 14,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ post: {
+ marginTop: 13,
+ },
+}));
diff --git a/frontend/app/screens/articles/blogposts.js b/frontend/app/screens/articles/blogposts.js
new file mode 100644
index 0000000..3ce4565
--- /dev/null
+++ b/frontend/app/screens/articles/blogposts.js
@@ -0,0 +1,88 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ Image,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkCard, RkStyleSheet,
+ RkText,
+} from 'react-native-ui-kitten';
+import { Avatar } from '../../components';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class Blogposts extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Blogposts'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getArticles('post'),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate('Article', { id: item.id });
+ };
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={() => this.onItemPressed(item)}>
+ <RkCard rkType='blog' style={styles.card}>
+ <Image rkCardImg source={item.photo} />
+ <View rkCardHeader style={styles.content}>
+ <RkText style={styles.section} rkType='header4'>{item.title}</RkText>
+ </View>
+ <View rkCardContent>
+ <View>
+ <RkText rkType='primary3 mediumLine' numberOfLines={2}>{item.text}</RkText>
+ </View>
+ </View>
+ <View rkCardFooter>
+ <View style={styles.userInfo}>
+ <Avatar style={styles.avatar} rkType='circle small' img={item.user.photo} />
+ <RkText rkType='header6'>{`${item.user.firstName} ${item.user.lastName}`}</RkText>
+ </View>
+ <RkText rkType='secondary2 hintColor'>{moment().add(item.time, 'seconds').fromNow()}</RkText>
+ </View>
+ </RkCard>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <FlatList
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.container}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingVertical: 8,
+ paddingHorizontal: 14,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ userInfo: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ avatar: {
+ marginRight: 17,
+ },
+}));
diff --git a/frontend/app/screens/articles/index.js b/frontend/app/screens/articles/index.js
new file mode 100644
index 0000000..115d2ac
--- /dev/null
+++ b/frontend/app/screens/articles/index.js
@@ -0,0 +1,6 @@
+export * from './articles1';
+export * from './articles2';
+export * from './articles3';
+export * from './articles4';
+export * from './blogposts';
+export * from './article';
diff --git a/frontend/app/screens/dashboard/dashboard.js b/frontend/app/screens/dashboard/dashboard.js
new file mode 100644
index 0000000..06c8d6a
--- /dev/null
+++ b/frontend/app/screens/dashboard/dashboard.js
@@ -0,0 +1,117 @@
+import React from 'react';
+import {
+ View,
+ ScrollView,
+} from 'react-native';
+import {
+ RkText,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import { FontAwesome } from '../../assets/icons';
+import {
+ ProgressChart,
+ DoughnutChart,
+ AreaChart,
+ AreaSmoothedChart,
+} from '../../components/';
+
+export class Dashboard extends React.Component {
+ static navigationOptions = {
+ title: 'Dashboard'.toUpperCase(),
+ };
+
+ state = {
+ data: {
+ statItems: [
+ {
+ name: 'Stars',
+ value: '4,512',
+ icon: 'github',
+ background: RkTheme.current.colors.dashboard.stars,
+ },
+ {
+ name: 'Tweets',
+ value: '2,256',
+ icon: 'twitter',
+ background: RkTheme.current.colors.dashboard.tweets,
+ },
+ {
+ name: 'Likes',
+ value: '1,124',
+ icon: 'facebook',
+ background: RkTheme.current.colors.dashboard.likes,
+ },
+ ],
+ },
+ };
+
+ renderStatItem = (item) => (
+ <View style={[styles.statItemContainer, { backgroundColor: item.background }]} key={item.name}>
+ <View>
+ <RkText rkType='header6' style={styles.statItemValue}>{item.value}</RkText>
+ <RkText rkType='secondary7' style={styles.statItemName}>{item.name}</RkText>
+ </View>
+ <RkText rkType='awesome hero' style={styles.statItemIcon}>{FontAwesome[item.icon]}</RkText>
+ </View>
+ );
+
+ render = () => {
+ const chartBackgroundStyle = { backgroundColor: RkTheme.current.colors.control.background };
+ return (
+ <ScrollView style={styles.screen}>
+ <View style={styles.statItems}>
+ {this.state.data.statItems.map(this.renderStatItem)}
+ </View>
+ <View style={[styles.chartBlock, chartBackgroundStyle]}>
+ <DoughnutChart />
+ </View>
+ <View style={[styles.chartBlock, chartBackgroundStyle]}>
+ <AreaChart />
+ </View>
+ <View style={[styles.chartBlock, chartBackgroundStyle]}>
+ <ProgressChart />
+ </View>
+ <View style={[styles.chartBlock, chartBackgroundStyle]}>
+ <AreaSmoothedChart />
+ </View>
+ </ScrollView>
+ );
+ };
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingHorizontal: 15,
+ },
+ statItems: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginVertical: 15,
+ },
+ statItemContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ borderRadius: 3,
+ paddingHorizontal: 10,
+ paddingVertical: 10,
+ },
+ statItemIcon: {
+ alignSelf: 'center',
+ marginLeft: 10,
+ color: 'white',
+ },
+ statItemValue: {
+ color: 'white',
+ },
+ statItemName: {
+ color: 'white',
+ },
+ chartBlock: {
+ padding: 15,
+ marginBottom: 15,
+ justifyContent: 'center',
+ },
+}));
+
diff --git a/frontend/app/screens/dashboard/index.js b/frontend/app/screens/dashboard/index.js
new file mode 100644
index 0000000..b58b6c9
--- /dev/null
+++ b/frontend/app/screens/dashboard/index.js
@@ -0,0 +1 @@
+export * from './dashboard';
diff --git a/frontend/app/screens/eCommerce/addToCardForm.js b/frontend/app/screens/eCommerce/addToCardForm.js
new file mode 100644
index 0000000..5d41885
--- /dev/null
+++ b/frontend/app/screens/eCommerce/addToCardForm.js
@@ -0,0 +1,138 @@
+import React from 'react';
+import axios from 'axios';
+import {
+ View,
+ Keyboard,
+} from 'react-native';
+import {
+ RkText,
+ RkTextInput,
+ RkStyleSheet,
+ RkAvoidKeyboard,
+} from 'react-native-ui-kitten';
+import { GradientButton } from '../../components/';
+import { PasswordTextInput } from '../../components/passwordTextInput';
+
+import { scale } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class AddToCardForm extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Add Card'.toUpperCase(),
+ };
+
+ state = {
+ name: '',
+ email: '',
+ problem: '',
+
+ };
+
+
+ onAddButtonPressed = () => {
+ axios.post('http://192.168.1.43:8000/api/articles/', {
+ title: this.state.problem.split(' ').slice(0, 5),
+ text: this.state.problem,
+
+ })
+ this.props.navigation.goBack();
+ };
+
+ render = () => (
+ <RkAvoidKeyboard
+ style={styles.screen}
+ onStartShouldSetResponder={() => true}
+ onResponderRelease={() => Keyboard.dismiss()}>
+ <View style={[styles.formContent]}>
+ <View>
+
+
+ <View style={[styles.content]}>
+ <View style={[styles.textRow]}>
+ <RkText rkType='subtitle'>Your name</RkText>
+ </View>
+ <RkTextInput
+ rkType='rounded'
+ onChangeText={(name) => this.setState({ name })}
+ value={this.state.name}
+ />
+ </View>
+
+ <View style={[styles.content]}>
+ <View style={[styles.textRow]}>
+ <RkText rkType='subtitle'>Your e-mail</RkText>
+ </View>
+ <RkTextInput
+ rkType='rounded'
+ onChangeText={(email) => this.setState({ email })}
+ value={this.state.email}
+ />
+ </View>
+
+ <View style={[styles.content]}>
+ <View style={[styles.textRow]}>
+ <RkText rkType='subtitle'>Describe eco-problem</RkText>
+ </View>
+ <RkTextInput
+ rkType='rounded'
+ onChangeText={(problem) => this.setState({ problem })}
+ value={this.state.problem}
+ />
+ </View>
+
+
+ </View>
+ <View>
+ <GradientButton
+ rkType='large'
+ text='ADD TO CARD'
+ onPress={this.onAddButtonPressed}
+ />
+ </View>
+ </View>
+ </RkAvoidKeyboard>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ padding: 15,
+ flex: 1,
+ backgroundColor: theme.colors.screen.base,
+ },
+ content: {
+ marginTop: 10,
+ },
+ formContent: {
+ justifyContent: 'space-between',
+ flexDirection: 'column',
+ flex: 1,
+ },
+ textRow: {
+ marginLeft: 20,
+ },
+ expireDateBlock: {
+ justifyContent: 'space-between',
+ flexDirection: 'row',
+ },
+ expireDateInput: {
+ flex: 0.48,
+ marginVertical: 10,
+ },
+ expireDateInnerInput: {
+ textAlign: 'center',
+ },
+ expireDateDelimiter: {
+ flex: 0.04,
+ },
+ balloon: {
+ maxWidth: scale(250),
+ padding: 15,
+ borderRadius: 100,
+ borderWidth: 0.5,
+ borderColor: theme.colors.border.solid,
+ },
+}));
diff --git a/frontend/app/screens/eCommerce/cards.js b/frontend/app/screens/eCommerce/cards.js
new file mode 100644
index 0000000..c22c30d
--- /dev/null
+++ b/frontend/app/screens/eCommerce/cards.js
@@ -0,0 +1,242 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ Image,
+ TouchableOpacity,
+ Modal,
+} from 'react-native';
+import {
+ RkText,
+ RkCard,
+ RkButton,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import { LinearGradient } from 'expo';
+import { data } from '../../data';
+import { PasswordTextInput } from '../../components/passwordTextInput';
+import { UIConstants } from '../../config/appConstants';
+import { scaleVertical } from '../../utils/scale';
+
+export class Cards extends React.Component {
+ static navigationOptions = {
+ title: 'Cards'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getCards(),
+ modalVisible: false,
+ };
+
+ getCardStyle = (type) => {
+ switch (type) {
+ case 'visa':
+ return {
+ gradient: RkTheme.current.colors.gradients.visa,
+ icon: require('../../assets/icons/visaIcon.png'),
+ };
+ case 'mastercard':
+ return {
+ gradient: RkTheme.current.colors.gradients.mastercard,
+ icon: require('../../assets/icons/masterCardIcon.png'),
+ };
+ case 'axp':
+ return {
+ gradient: RkTheme.current.colors.gradients.axp,
+ icon: require('../../assets/icons/americanExpressIcon.png'),
+ };
+ default: return {};
+ }
+ };
+
+ formatCurrency = (amount, currency) => {
+ switch (currency) {
+ case 'usd':
+ return `$${amount}`;
+ case 'eur':
+ return `€${amount}`;
+ default: return '';
+ }
+ };
+
+ prepareCardNo = (cardNo) => {
+ const re = /\*+/;
+ const parts = cardNo.split(re);
+ return {
+ firstPart: parts[0],
+ lastPart: parts[1],
+ };
+ };
+
+ renderFooter = () => (
+ <View style={styles.footer}>
+ <RkButton style={styles.button} rkType='circle highlight'>
+ <Image source={require('../../assets/icons/iconPlus.png')} />
+ </RkButton>
+ </View>
+ );
+
+ setModalVisible = (visible) => {
+ this.setState({ modalVisible: visible });
+ };
+
+ onItemPressed = () => {
+ this.setModalVisible(true);
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ renderItem = ({ item }) => {
+ const { gradient, icon } = this.getCardStyle(item.type);
+ const { firstPart, lastPart } = this.prepareCardNo(item.cardNo);
+
+ return (
+ <RkCard rkType='credit' style={styles.card}>
+ <TouchableOpacity
+ delayPressIn={70}
+ activeOpacity={0.8}
+ onPress={this.onItemPressed}>
+ <LinearGradient
+ colors={gradient}
+ start={{ x: 0.0, y: 0.5 }}
+ end={{ x: 1, y: 0.5 }}
+ style={styles.background}>
+ <View rkCardHeader>
+ <RkText rkType='header4 inverseColor'>{item.bank}</RkText>
+ <Image source={icon} />
+ </View>
+ <View rkCardContent>
+ <View style={styles.cardNoContainer}>
+ <RkText style={styles.cardNo} rkType='header2 inverseColor'>{firstPart}</RkText>
+ <RkText style={[styles.cardNo, styles.cardPlaceholder]} rkType='header2 inverseColor'>* * * *</RkText>
+ <RkText style={[styles.cardNo, styles.cardPlaceholder]} rkType='header2 inverseColor'>* * * *</RkText>
+ <RkText style={styles.cardNo} rkType='header2 inverseColor'>{lastPart}</RkText>
+ </View>
+ <RkText style={styles.date} rkType='header6 inverseColor'>{item.date}</RkText>
+ </View>
+ <View rkCardFooter>
+ <View>
+ <RkText rkType='header4 inverseColor'>{item.currency.toUpperCase()}</RkText>
+ <RkText rkType='header6 inverseColor'>{item.name.toUpperCase()}</RkText>
+ </View>
+ <RkText
+ rkType='header2 inverseColor'>{this.formatCurrency(item.amount, item.currency)}
+ </RkText>
+ </View>
+ </LinearGradient>
+ </TouchableOpacity>
+ </RkCard>
+ );
+ };
+
+ render = () => (
+ <View style={styles.root}>
+ <FlatList
+ style={styles.list}
+ showsVerticalScrollIndicator={false}
+ ListFooterComponent={this.renderFooter}
+ keyExtractor={this.extractItemKey}
+ data={this.state.data}
+ renderItem={this.renderItem}
+ />
+ <Modal
+ animationType="fade"
+ transparent
+ onRequestClose={() => this.setModalVisible(false)}
+ visible={this.state.modalVisible}>
+ <View style={styles.popupOverlay}>
+ <View style={styles.popup}>
+ <View style={styles.popupContent}>
+ <RkText style={styles.popupHeader} rkType='header4'>Enter security code</RkText>
+ <PasswordTextInput />
+ </View>
+ <View style={styles.popupButtons}>
+ <RkButton
+ onPress={() => this.setModalVisible(false)}
+ style={styles.popupButton}
+ rkType='clear'>
+ <RkText rkType='light'>CANCEL</RkText>
+ </RkButton>
+ <View style={styles.separator} />
+ <RkButton
+ onPress={() => this.setModalVisible(false)}
+ style={styles.popupButton}
+ rkType='clear'>
+ <RkText>OK</RkText>
+ </RkButton>
+ </View>
+ </View>
+ </View>
+ </Modal>
+ </View>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ list: {
+ marginHorizontal: 16,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ background: {
+ borderRadius: 7,
+ },
+ cardNoContainer: {
+ flexDirection: 'row',
+ },
+ cardNo: {
+ marginHorizontal: 8,
+ },
+ cardPlaceholder: {
+ paddingTop: 4,
+ },
+ date: {
+ marginTop: scaleVertical(20),
+ },
+ footer: {
+ marginTop: 8,
+ marginBottom: scaleVertical(16),
+ alignItems: 'center',
+ },
+ button: {
+ height: 56,
+ width: 56,
+ },
+ popup: {
+ backgroundColor: theme.colors.screen.base,
+ marginTop: scaleVertical(70),
+ marginHorizontal: 37,
+ borderRadius: 7,
+ },
+ popupOverlay: {
+ backgroundColor: theme.colors.screen.overlay,
+ flex: 1,
+ marginTop: UIConstants.HeaderHeight,
+ },
+ popupContent: {
+ alignItems: 'center',
+ margin: 16,
+ },
+ popupHeader: {
+ marginBottom: scaleVertical(45),
+ },
+ popupButtons: {
+ marginTop: 15,
+ flexDirection: 'row',
+ borderTopWidth: 1,
+ borderColor: theme.colors.border.base,
+ },
+ popupButton: {
+ flex: 1,
+ marginVertical: 16,
+ },
+ separator: {
+ backgroundColor: theme.colors.border.base,
+ width: 1,
+ },
+}));
diff --git a/frontend/app/screens/eCommerce/index.js b/frontend/app/screens/eCommerce/index.js
new file mode 100644
index 0000000..7658d81
--- /dev/null
+++ b/frontend/app/screens/eCommerce/index.js
@@ -0,0 +1,2 @@
+export * from './cards';
+export * from './addToCardForm';
diff --git a/frontend/app/screens/index.js b/frontend/app/screens/index.js
new file mode 100644
index 0000000..b7ce1cb
--- /dev/null
+++ b/frontend/app/screens/index.js
@@ -0,0 +1,11 @@
+export * from './navigation';
+export * from './menu';
+export * from './other';
+export * from './dashboard';
+export * from './social';
+export * from './articles';
+export * from './messaging';
+export * from './login';
+export * from './walkthroughs';
+export * from './eCommerce';
+export * from './theme';
diff --git a/frontend/app/screens/login/index.js b/frontend/app/screens/login/index.js
new file mode 100644
index 0000000..b0b1cd1
--- /dev/null
+++ b/frontend/app/screens/login/index.js
@@ -0,0 +1,4 @@
+export * from './login1';
+export * from './login2';
+export * from './signUp';
+export * from './passwordRecovery';
diff --git a/frontend/app/screens/login/login1.js b/frontend/app/screens/login/login1.js
new file mode 100644
index 0000000..73e97d5
--- /dev/null
+++ b/frontend/app/screens/login/login1.js
@@ -0,0 +1,129 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ Dimensions,
+ Keyboard,
+} from 'react-native';
+import {
+ RkButton,
+ RkText,
+ RkTextInput,
+ RkAvoidKeyboard,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import { FontAwesome } from '../../assets/icons';
+import { GradientButton } from '../../components/gradientButton';
+import { scaleModerate, scaleVertical } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class LoginV1 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ header: null,
+ };
+
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/backgroundLoginV1.png') : require('../../assets/images/backgroundLoginV1DarkTheme.png')
+ );
+
+ renderImage = () => {
+ const screenSize = Dimensions.get('window');
+ const imageSize = {
+ width: screenSize.width,
+ height: screenSize.height - scaleModerate(375, 1),
+ };
+ return (
+ <Image
+ style={[styles.image, imageSize]}
+ source={this.getThemeImageSource(RkTheme.current)}
+ />
+ );
+ };
+
+ onLoginButtonPressed = () => {
+ this.props.navigation.goBack();
+ };
+
+ onSignUpButtonPressed = () => {
+ this.props.navigation.navigate('SignUp');
+ };
+
+ render = () => (
+ <RkAvoidKeyboard
+ onStartShouldSetResponder={() => true}
+ onResponderRelease={() => Keyboard.dismiss()}
+ style={styles.screen}>
+ {this.renderImage()}
+ <View style={styles.container}>
+ <View style={styles.buttons}>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero accentColor'>{FontAwesome.twitter}</RkText>
+ </RkButton>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero accentColor'>{FontAwesome.google}</RkText>
+ </RkButton>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero accentColor'>{FontAwesome.facebook}</RkText>
+ </RkButton>
+ </View>
+ <RkTextInput rkType='rounded' placeholder='Username' />
+ <RkTextInput rkType='rounded' placeholder='Password' secureTextEntry />
+ <GradientButton
+ style={styles.save}
+ rkType='large'
+ onPress={this.onLoginButtonPressed}
+ text='LOGIN'
+ />
+ <View style={styles.footer}>
+ <View style={styles.textRow}>
+ <RkText rkType='primary3'>Don’t have an account?</RkText>
+ <RkButton rkType='clear'>
+ <RkText rkType='header6' onPress={this.onSignUpButtonPressed}>Sign up now</RkText>
+ </RkButton>
+ </View>
+ </View>
+ </View>
+ </RkAvoidKeyboard>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ flex: 1,
+ alignItems: 'center',
+ backgroundColor: theme.colors.screen.base,
+ },
+ image: {
+ resizeMode: 'cover',
+ marginBottom: scaleVertical(10),
+ },
+ container: {
+ paddingHorizontal: 17,
+ paddingBottom: scaleVertical(22),
+ alignItems: 'center',
+ flex: -1,
+ },
+ footer: {
+ justifyContent: 'flex-end',
+ flex: 1,
+ },
+ buttons: {
+ flexDirection: 'row',
+ marginBottom: scaleVertical(24),
+ },
+ button: {
+ marginHorizontal: 14,
+ },
+ save: {
+ marginVertical: 9,
+ },
+ textRow: {
+ justifyContent: 'center',
+ flexDirection: 'row',
+ },
+}));
diff --git a/frontend/app/screens/login/login2.js b/frontend/app/screens/login/login2.js
new file mode 100644
index 0000000..c211190
--- /dev/null
+++ b/frontend/app/screens/login/login2.js
@@ -0,0 +1,127 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ Keyboard,
+} from 'react-native';
+import {
+ RkButton,
+ RkText,
+ RkTextInput,
+ RkAvoidKeyboard,
+ RkTheme,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { FontAwesome } from '../../assets/icons';
+import { GradientButton } from '../../components/gradientButton';
+import { scaleVertical } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class LoginV2 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ header: null,
+ };
+
+ onLoginButtonPressed = () => {
+ this.props.navigation.goBack();
+ };
+
+ onSignUpButtonPressed = () => {
+ this.props.navigation.navigate('SignUp');
+ };
+
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/logo.png') : require('../../assets/images/logoDark.png')
+ );
+
+ renderImage = () => (
+ <Image style={styles.image} source={this.getThemeImageSource(RkTheme.current)} />
+ );
+
+ render = () => (
+ <RkAvoidKeyboard
+ style={styles.screen}
+ onStartShouldSetResponder={() => true}
+ onResponderRelease={() => Keyboard.dismiss()}>
+ <View style={styles.header}>
+ {this.renderImage()}
+ <RkText rkType='light h1'>React Native</RkText>
+ <RkText rkType='logo h0'>UI Kitten</RkText>
+ </View>
+ <View style={styles.content}>
+ <View>
+ <RkTextInput rkType='rounded' placeholder='Username' />
+ <RkTextInput rkType='rounded' placeholder='Password' secureTextEntry />
+ <GradientButton
+ style={styles.save}
+ rkType='large'
+ text='LOGIN'
+ onPress={this.onLoginButtonPressed}
+ />
+ </View>
+ <View style={styles.buttons}>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero'>{FontAwesome.twitter}</RkText>
+ </RkButton>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero'>{FontAwesome.google}</RkText>
+ </RkButton>
+ <RkButton style={styles.button} rkType='social'>
+ <RkText rkType='awesome hero'>{FontAwesome.facebook}</RkText>
+ </RkButton>
+ </View>
+ <View style={styles.footer}>
+ <View style={styles.textRow}>
+ <RkText rkType='primary3'>Don’t have an account?</RkText>
+ <RkButton rkType='clear' onPress={this.onSignUpButtonPressed}>
+ <RkText rkType='header6'>Sign up now</RkText>
+ </RkButton>
+ </View>
+ </View>
+ </View>
+ </RkAvoidKeyboard>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ padding: scaleVertical(16),
+ flex: 1,
+ justifyContent: 'space-between',
+ backgroundColor: theme.colors.screen.base,
+ },
+ image: {
+ height: scaleVertical(77),
+ resizeMode: 'contain',
+ },
+ header: {
+ paddingBottom: scaleVertical(10),
+ alignItems: 'center',
+ justifyContent: 'center',
+ flex: 1,
+ },
+ content: {
+ justifyContent: 'space-between',
+ },
+ save: {
+ marginVertical: 20,
+ },
+ buttons: {
+ flexDirection: 'row',
+ marginBottom: scaleVertical(24),
+ marginHorizontal: 24,
+ justifyContent: 'space-around',
+ },
+ textRow: {
+ flexDirection: 'row',
+ justifyContent: 'center',
+ },
+ button: {
+ borderColor: theme.colors.border.solid,
+ },
+ footer: {},
+}));
diff --git a/frontend/app/screens/login/passwordRecovery.js b/frontend/app/screens/login/passwordRecovery.js
new file mode 100644
index 0000000..b383e4c
--- /dev/null
+++ b/frontend/app/screens/login/passwordRecovery.js
@@ -0,0 +1,83 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ Keyboard,
+} from 'react-native';
+import {
+ RkStyleSheet,
+ RkText,
+ RkTextInput,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import { GradientButton } from '../../components/';
+import { scaleVertical } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class PasswordRecovery extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ header: null,
+ };
+
+ onSendButtonPressed = () => {
+ this.props.navigation.goBack();
+ };
+
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/logo.png') : require('../../assets/images/logoDark.png')
+ );
+
+ renderImage = () => (
+ <Image style={styles.image} source={this.getThemeImageSource(RkTheme.current)} />
+ );
+
+ render = () => (
+ <View
+ behavior='position'
+ style={styles.screen}
+ onStartShouldSetResponder={() => true}
+ onResponderRelease={() => Keyboard.dismiss()}>
+ <View style={styles.header}>
+ {this.renderImage()}
+ <RkText rkType='h1'>Password Recovery</RkText>
+ </View>
+ <View style={styles.content}>
+ <RkTextInput rkType='rounded' placeholder='Email' />
+ <RkText rkType='secondary5 secondaryColor center'>
+ Enter your email below to receive your password reset instructions
+ </RkText>
+ </View>
+ <GradientButton
+ style={styles.save}
+ rkType='large'
+ text='SEND'
+ onPress={this.onSendButtonPressed}
+ />
+ </View>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ flex: 1,
+ paddingHorizontal: 16,
+ paddingVertical: scaleVertical(24),
+ justifyContent: 'space-between',
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ alignItems: 'center',
+ },
+ image: {
+ marginVertical: scaleVertical(27),
+ height: scaleVertical(77),
+ resizeMode: 'contain',
+ },
+ content: {
+ alignItems: 'center',
+ },
+}));
diff --git a/frontend/app/screens/login/signUp.js b/frontend/app/screens/login/signUp.js
new file mode 100644
index 0000000..5c7965e
--- /dev/null
+++ b/frontend/app/screens/login/signUp.js
@@ -0,0 +1,110 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ Keyboard,
+} from 'react-native';
+import {
+ RkButton,
+ RkText,
+ RkTextInput,
+ RkStyleSheet,
+ RkTheme,
+ RkAvoidKeyboard,
+} from 'react-native-ui-kitten';
+import { GradientButton } from '../../components/';
+import { scaleVertical } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class SignUp extends React.Component {
+ static navigationOptions = {
+ header: null,
+ };
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/logo.png') : require('../../assets/images/logoDark.png')
+ );
+
+ renderImage = () => (
+ <Image style={styles.image} source={this.getThemeImageSource(RkTheme.current)} />
+ );
+
+ onSignUpButtonPressed = () => {
+ this.props.navigation.goBack();
+ };
+
+ onSignInButtonPressed = () => {
+ this.props.navigation.navigate('Login1');
+ };
+
+ render = () => (
+ <RkAvoidKeyboard
+ style={styles.screen}
+ onStartShouldSetResponder={() => true}
+ onResponderRelease={() => Keyboard.dismiss()}>
+ <View style={{ alignItems: 'center' }}>
+ {this.renderImage()}
+ <RkText rkType='h1'>Registration</RkText>
+ </View>
+ <View style={styles.content}>
+ <View>
+ <RkTextInput rkType='rounded' placeholder='Name' />
+ <RkTextInput rkType='rounded' placeholder='Email' />
+ <RkTextInput rkType='rounded' placeholder='Password' secureTextEntry />
+ <RkTextInput rkType='rounded' placeholder='Confirm Password' secureTextEntry />
+ <GradientButton
+ style={styles.save}
+ rkType='large'
+ text='SIGN UP'
+ onPress={this.onSignUpButtonPressed}
+ />
+ </View>
+ <View style={styles.footer}>
+ <View style={styles.textRow}>
+ <RkText rkType='primary3'>Already have an account?</RkText>
+ <RkButton rkType='clear' onPress={this.onSignInButtonPressed}>
+ <RkText rkType='header6'>Sign in now</RkText>
+ </RkButton>
+ </View>
+ </View>
+ </View>
+ </RkAvoidKeyboard>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ padding: 16,
+ flex: 1,
+ justifyContent: 'space-around',
+ backgroundColor: theme.colors.screen.base,
+ },
+ image: {
+ marginBottom: 10,
+ height: scaleVertical(77),
+ resizeMode: 'contain',
+ },
+ content: {
+ justifyContent: 'space-between',
+ },
+ save: {
+ marginVertical: 20,
+ },
+ buttons: {
+ flexDirection: 'row',
+ marginBottom: 24,
+ marginHorizontal: 24,
+ justifyContent: 'space-around',
+ },
+ footer: {
+ justifyContent: 'flex-end',
+ },
+ textRow: {
+ flexDirection: 'row',
+ justifyContent: 'center',
+ },
+}));
diff --git a/frontend/app/screens/menu/categoryMenu.js b/frontend/app/screens/menu/categoryMenu.js
new file mode 100644
index 0000000..6ed6400
--- /dev/null
+++ b/frontend/app/screens/menu/categoryMenu.js
@@ -0,0 +1,77 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {
+ TouchableHighlight,
+ View,
+ FlatList,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkStyleSheet,
+ RkTheme,
+ RkText,
+} from 'react-native-ui-kitten';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class CategoryMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ items: PropTypes.arrayOf(PropTypes.shape({
+ title: PropTypes.string.isRequired,
+ })).isRequired,
+ };
+
+ onItemPressed = (item) => {
+ const url = item.action || item.id;
+ this.props.navigation.navigate(url);
+ };
+
+ extractItemKey = (item) => item.id;
+
+ renderItem = ({ item }) => (
+ <TouchableHighlight
+ style={styles.item}
+ underlayColor={RkTheme.current.colors.button.underlay}
+ activeOpacity={1}
+ onPress={() => this.onItemPressed(item)}>
+ <View>
+ <RkText>{item.title}</RkText>
+ </View>
+ </TouchableHighlight>
+ );
+
+ renderPlaceholder = () => (
+ <View style={styles.emptyContainer}>
+ <RkText rkType='light subtitle'>Coming Soon...</RkText>
+ </View>
+ );
+
+ renderList = () => (
+ <FlatList
+ style={styles.list}
+ data={this.props.items}
+ keyExtractor={this.extractItemKey}
+ renderItem={this.renderItem}
+ />
+ );
+
+ render = () => (this.props.items.length === 0 ? this.renderPlaceholder() : this.renderList());
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ item: {
+ paddingVertical: 32.5,
+ paddingHorizontal: 16.5,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ },
+ list: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ emptyContainer: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ backgroundColor: theme.colors.screen.base,
+ },
+}));
diff --git a/frontend/app/screens/menu/index.js b/frontend/app/screens/menu/index.js
new file mode 100644
index 0000000..4bea133
--- /dev/null
+++ b/frontend/app/screens/menu/index.js
@@ -0,0 +1,2 @@
+export * from './categoryMenu';
+export * from './menus';
diff --git a/frontend/app/screens/menu/menus.js b/frontend/app/screens/menu/menus.js
new file mode 100644
index 0000000..8cd8ff2
--- /dev/null
+++ b/frontend/app/screens/menu/menus.js
@@ -0,0 +1,114 @@
+/* eslint-disable react/no-multi-comp */
+import React from 'react';
+
+import { CategoryMenu } from './categoryMenu';
+import * as Routes from '../../config/navigation/routesBuilder';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class LoginMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Login'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.LoginRoutes} />
+ );
+}
+
+export class NavigationMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Navigation'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.NavigationRoutes} />
+ );
+}
+
+export class SocialMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Social'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.SocialRoutes} />
+ );
+}
+
+export class ArticleMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Articles'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.ArticleRoutes} />
+ );
+}
+
+export class MessagingMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Messaging'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.MessagingRoutes} />
+ );
+}
+
+export class DashboardMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Dashboards'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.DashboardRoutes} />
+ );
+}
+
+export class WalkthroughMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Walkthrough'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.WalkthroughRoutes} />
+ );
+}
+
+export class EcommerceMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Ecommerce'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.EcommerceRoutes} />
+ );
+}
+
+export class OtherMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Other'.toUpperCase(),
+ };
+ render = () => (
+ <CategoryMenu navigation={this.props.navigation} items={Routes.OtherRoutes} />
+ );
+}
diff --git a/frontend/app/screens/messaging/chat.js b/frontend/app/screens/messaging/chat.js
new file mode 100644
index 0000000..c6b0b5e
--- /dev/null
+++ b/frontend/app/screens/messaging/chat.js
@@ -0,0 +1,214 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ Platform,
+ Image,
+ TouchableOpacity,
+ Keyboard,
+ InteractionManager,
+} from 'react-native';
+import {
+ RkButton,
+ RkText,
+ RkTextInput,
+ RkAvoidKeyboard,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import _ from 'lodash';
+import { FontAwesome } from '../../assets/icons';
+import { data } from '../../data';
+import { Avatar } from '../../components/avatar';
+import { scale } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class Chat extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = ({ navigation }) => {
+ const userId = navigation.state.params ? navigation.state.params.userId : undefined;
+ const user = data.getUser(userId);
+ return ({
+ headerTitle: Chat.renderNavigationTitle(navigation, user),
+ headerRight: Chat.renderNavigationAvatar(navigation, user),
+ });
+ };
+
+ constructor(props) {
+ super(props);
+ const userId = this.props.navigation.getParam('userId', undefined);
+ this.state = {
+ data: data.getConversation(userId),
+ };
+ }
+
+ componentDidMount() {
+ InteractionManager.runAfterInteractions(() => {
+ this.listRef.scrollToEnd();
+ });
+ }
+
+ setListRef = (ref) => {
+ this.listRef = ref;
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ scrollToEnd = () => {
+ if (Platform.OS === 'ios') {
+ this.listRef.scrollToEnd();
+ } else {
+ _.delay(this.listRef.scrollToEnd, 100);
+ }
+ };
+
+ onInputChanged = (text) => {
+ this.setState({ message: text });
+ };
+
+ onSendButtonPressed = () => {
+ if (!this.state.message) {
+ return;
+ }
+ this.state.data.messages.push({
+ id: this.state.data.messages.length, time: 0, type: 'out', text: this.state.message,
+ });
+ this.setState({ message: '' });
+ this.scrollToEnd(true);
+ };
+
+ static onNavigationTitlePressed = (navigation, user) => {
+ navigation.navigate('ProfileV1', { id: user.id });
+ };
+
+ static onNavigationAvatarPressed = (navigation, user) => {
+ navigation.navigate('ProfileV1', { id: user.id });
+ };
+
+ static renderNavigationTitle = (navigation, user) => (
+ <TouchableOpacity onPress={() => Chat.onNavigationTitlePressed(navigation, user)}>
+ <View style={styles.header}>
+ <RkText rkType='header5'>{`${user.firstName} ${user.lastName}`}</RkText>
+ <RkText rkType='secondary3 secondaryColor'>Online</RkText>
+ </View>
+ </TouchableOpacity>
+ );
+
+ static renderNavigationAvatar = (navigation, user) => (
+ <TouchableOpacity onPress={() => Chat.onNavigationAvatarPressed(navigation, user)}>
+ <Avatar style={styles.avatar} rkType='small' img={user.photo} />
+ </TouchableOpacity>
+ );
+
+ renderDate = (date) => (
+ <RkText style={styles.time} rkType='secondary7 hintColor'>
+ {moment().add(date, 'seconds').format('LT')}
+ </RkText>
+ );
+
+ renderItem = ({ item }) => {
+ const isIncoming = item.type === 'in';
+ const backgroundColor = isIncoming
+ ? RkTheme.current.colors.chat.messageInBackground
+ : RkTheme.current.colors.chat.messageOutBackground;
+ const itemStyle = isIncoming ? styles.itemIn : styles.itemOut;
+
+ return (
+ <View style={[styles.item, itemStyle]}>
+ {!isIncoming && this.renderDate(item.time)}
+ <View style={[styles.balloon, { backgroundColor }]}>
+ <RkText rkType='primary2 mediumLine chat' style={{ paddingTop: 5 }}>{item.text}</RkText>
+ </View>
+ {isIncoming && this.renderDate(item.time)}
+ </View>
+ );
+ };
+
+ render = () => (
+ <RkAvoidKeyboard
+ style={styles.container}
+ onResponderRelease={Keyboard.dismiss}>
+ <FlatList
+ ref={this.setListRef}
+ extraData={this.state}
+ style={styles.list}
+ data={this.state.data.messages}
+ keyExtractor={this.extractItemKey}
+ renderItem={this.renderItem}
+ />
+ <View style={styles.footer}>
+ <RkButton style={styles.plus} rkType='clear'>
+ <RkText rkType='awesome secondaryColor'>{FontAwesome.plus}</RkText>
+ </RkButton>
+ <RkTextInput
+ onFocus={this.scrollToEnd}
+ onBlur={this.scrollToEnd}
+ onChangeText={this.onInputChanged}
+ value={this.state.message}
+ rkType='row sticker'
+ placeholder="Add a comment..."
+ />
+ <RkButton onPress={this.onSendButtonPressed} style={styles.send} rkType='circle highlight'>
+ <Image source={require('../../assets/icons/sendIcon.png')} />
+ </RkButton>
+ </View>
+ </RkAvoidKeyboard>
+
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ header: {
+ alignItems: 'center',
+ },
+ avatar: {
+ marginRight: 16,
+ },
+ container: {
+ flex: 1,
+ backgroundColor: theme.colors.screen.base,
+ },
+ list: {
+ paddingHorizontal: 17,
+ },
+ footer: {
+ flexDirection: 'row',
+ minHeight: 60,
+ padding: 10,
+ backgroundColor: theme.colors.screen.alter,
+ },
+ item: {
+ marginVertical: 14,
+ flex: 1,
+ flexDirection: 'row',
+ },
+ itemIn: {},
+ itemOut: {
+ alignSelf: 'flex-end',
+ },
+ balloon: {
+ maxWidth: scale(250),
+ paddingHorizontal: 15,
+ paddingTop: 10,
+ paddingBottom: 15,
+ borderRadius: 20,
+ },
+ time: {
+ alignSelf: 'flex-end',
+ margin: 15,
+ },
+ plus: {
+ paddingVertical: 10,
+ paddingHorizontal: 10,
+ marginRight: 7,
+ },
+ send: {
+ width: 40,
+ height: 40,
+ marginLeft: 10,
+ },
+}));
diff --git a/frontend/app/screens/messaging/chatList.js b/frontend/app/screens/messaging/chatList.js
new file mode 100644
index 0000000..36cde5c
--- /dev/null
+++ b/frontend/app/screens/messaging/chatList.js
@@ -0,0 +1,147 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ StyleSheet,
+ TouchableOpacity,
+} from 'react-native';
+import _ from 'lodash';
+import {
+ RkStyleSheet,
+ RkText,
+ RkTextInput,
+} from 'react-native-ui-kitten';
+import { Avatar } from '../../components';
+import { FontAwesome } from '../../assets/icons';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class ChatList extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Chats List'.toUpperCase(),
+ };
+
+ state = {
+ data: {
+ original: data.getChatList(),
+ filtered: data.getChatList(),
+ },
+ };
+
+ extractItemKey = (item) => `${item.withUser.id}`;
+
+ onInputChanged = (event) => {
+ const pattern = new RegExp(event.nativeEvent.text, 'i');
+ const chats = _.filter(this.state.data.original, chat => {
+ const filterResult = {
+ firstName: chat.withUser.firstName.search(pattern),
+ lastName: chat.withUser.lastName.search(pattern),
+ };
+ return filterResult.firstName !== -1 || filterResult.lastName !== -1 ? chat : undefined;
+ });
+ this.setState({
+ data: {
+ original: this.state.data.original,
+ filtered: chats,
+ },
+ });
+ };
+
+ onItemPressed = (item) => {
+ const navigationParams = { userId: item.withUser.id };
+ this.props.navigation.navigate('Chat', navigationParams);
+ };
+
+ renderSeparator = () => (
+ <View style={styles.separator} />
+ );
+
+ renderInputLabel = () => (
+ <RkText rkType='awesome'>{FontAwesome.search}</RkText>
+ );
+
+ renderHeader = () => (
+ <View style={styles.searchContainer}>
+ <RkTextInput
+ autoCapitalize='none'
+ autoCorrect={false}
+ onChange={this.onInputChanged}
+ label={this.renderInputLabel()}
+ rkType='row'
+ placeholder='Search'
+ />
+ </View>
+ );
+
+ renderItem = ({ item }) => {
+ const last = item.messages[item.messages.length - 1];
+ return (
+ <TouchableOpacity onPress={() => this.onItemPressed(item)}>
+ <View style={styles.container}>
+ <Avatar rkType='circle' style={styles.avatar} img={item.withUser.photo} />
+ <View style={styles.content}>
+ <View style={styles.contentHeader}>
+ <RkText rkType='header5'>{`${item.withUser.firstName} ${item.withUser.lastName}`}</RkText>
+ <RkText rkType='secondary4 hintColor'>
+ {moment().add(last.time, 'seconds').format('LT')}
+ </RkText>
+ </View>
+ <RkText numberOfLines={2} rkType='primary3 mediumLine' style={{ paddingTop: 5 }}>
+ {last.text}
+ </RkText>
+ </View>
+ </View>
+ </TouchableOpacity>
+ );
+ };
+
+ render = () => (
+ <FlatList
+ style={styles.root}
+ data={this.state.data.filtered}
+ extraData={this.state}
+ ListHeaderComponent={this.renderHeader}
+ ItemSeparatorComponent={this.renderSeparator}
+ keyExtractor={this.extractItemKey}
+ renderItem={this.renderItem}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ searchContainer: {
+ backgroundColor: theme.colors.screen.bold,
+ paddingHorizontal: 16,
+ paddingVertical: 10,
+ height: 60,
+ alignItems: 'center',
+ },
+ container: {
+ paddingLeft: 19,
+ paddingRight: 16,
+ paddingBottom: 12,
+ paddingTop: 7,
+ flexDirection: 'row',
+ },
+ content: {
+ marginLeft: 16,
+ flex: 1,
+ },
+ contentHeader: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginBottom: 6,
+ },
+ separator: {
+ height: StyleSheet.hairlineWidth,
+ backgroundColor: theme.colors.border.base,
+ },
+}));
diff --git a/frontend/app/screens/messaging/comments.js b/frontend/app/screens/messaging/comments.js
new file mode 100644
index 0000000..3b772c5
--- /dev/null
+++ b/frontend/app/screens/messaging/comments.js
@@ -0,0 +1,98 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ StyleSheet,
+ TouchableOpacity,
+} from 'react-native';
+import {
+ RkStyleSheet,
+ RkText,
+} from 'react-native-ui-kitten';
+import { Avatar } from '../../components';
+import { data } from '../../data';
+import NavigationType from '../../config/navigation/propTypes';
+
+const moment = require('moment');
+
+export class Comments extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Comments'.toUpperCase(),
+ };
+
+ constructor(props) {
+ super(props);
+ const postId = this.props.navigation.getParam('postId', undefined);
+ this.state = {
+ data: data.getComments(postId),
+ };
+ }
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onItemPressed = (item) => {
+ const navigationParams = { id: item.user.id };
+ this.props.navigation.navigate('ProfileV1', navigationParams);
+ };
+
+ renderSeparator = () => (
+ <View style={styles.separator} />
+ );
+
+ renderItem = ({ item }) => (
+ <View style={styles.container}>
+ <TouchableOpacity onPress={() => this.onItemPressed(item)}>
+ <Avatar rkType='circle' style={styles.avatar} img={item.user.photo} />
+ </TouchableOpacity>
+ <View style={styles.content}>
+ <View style={styles.contentHeader}>
+ <RkText rkType='header5'>{`${item.user.firstName} ${item.user.lastName}`}</RkText>
+ <RkText rkType='secondary4 hintColor'>
+ {moment().add(item.time, 'seconds').format('LT')}
+ </RkText>
+ </View>
+ <RkText rkType='primary3 mediumLine'>{item.text}</RkText>
+ </View>
+ </View>
+ );
+
+ render = () => (
+ <FlatList
+ style={styles.root}
+ data={this.state.data}
+ extraData={this.state}
+ ItemSeparatorComponent={this.renderSeparator}
+ keyExtractor={this.extractItemKey}
+ renderItem={this.renderItem}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ container: {
+ paddingLeft: 19,
+ paddingRight: 16,
+ paddingVertical: 12,
+ flexDirection: 'row',
+ alignItems: 'flex-start',
+ },
+ content: {
+ marginLeft: 16,
+ flex: 1,
+ },
+ contentHeader: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginBottom: 6,
+ },
+ separator: {
+ height: StyleSheet.hairlineWidth,
+ backgroundColor: theme.colors.border.base,
+ },
+}));
diff --git a/frontend/app/screens/messaging/index.js b/frontend/app/screens/messaging/index.js
new file mode 100644
index 0000000..0d39244
--- /dev/null
+++ b/frontend/app/screens/messaging/index.js
@@ -0,0 +1,3 @@
+export * from './chat';
+export * from './chatList';
+export * from './comments';
diff --git a/frontend/app/screens/navigation/grid.js b/frontend/app/screens/navigation/grid.js
new file mode 100644
index 0000000..7fbe404
--- /dev/null
+++ b/frontend/app/screens/navigation/grid.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import {
+ ScrollView,
+ Dimensions,
+} from 'react-native';
+import {
+ RkButton, RkStyleSheet,
+ RkText,
+} from 'react-native-ui-kitten';
+import { MainRoutes } from '../../config/navigation/routes';
+import NavigationType from '../../config/navigation/propTypes';
+
+const paddingValue = 8;
+
+export class GridV1 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Grid Menu'.toUpperCase(),
+ };
+
+ constructor(props) {
+ super(props);
+ const screenWidth = Dimensions.get('window').width;
+ this.itemSize = {
+ width: (screenWidth - (paddingValue * 6)) / 2,
+ height: (screenWidth - (paddingValue * 6)) / 2,
+ };
+ }
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate(item.id);
+ };
+
+ renderItems = () => MainRoutes.map(route => (
+ <RkButton
+ rkType='square shadow'
+ style={{ ...this.itemSize }}
+ key={route.id}
+ onPress={() => this.onItemPressed(route)}>
+ <RkText style={styles.icon} rkType='primary moon menuIcon'>
+ {route.icon}
+ </RkText>
+ <RkText>{route.title}</RkText>
+ </RkButton>
+ ));
+
+ render = () => (
+ <ScrollView
+ style={styles.root}
+ contentContainerStyle={styles.rootContainer}>
+ {this.renderItems()}
+ </ScrollView>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.scroll,
+ padding: paddingValue,
+ },
+ rootContainer: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ },
+ icon: {
+ marginBottom: 16,
+ },
+}));
diff --git a/frontend/app/screens/navigation/grid2.js b/frontend/app/screens/navigation/grid2.js
new file mode 100644
index 0000000..8773e02
--- /dev/null
+++ b/frontend/app/screens/navigation/grid2.js
@@ -0,0 +1,82 @@
+import React from 'react';
+import {
+ ScrollView,
+ View,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkText,
+ RkButton,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { MainRoutes } from '../../config/navigation/routes';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class GridV2 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Grid Menu'.toUpperCase(),
+ };
+
+ state = {
+ dimensions: undefined,
+ };
+
+ onContainerLayout = (event) => {
+ if (this.state.height) {
+ return;
+ }
+ const dimensions = event.nativeEvent.layout;
+ this.setState({ dimensions });
+ };
+
+ renderItems = () => MainRoutes.map(this.renderItem);
+
+ renderItem = (item) => (
+ <RkButton
+ rkType='tile'
+ style={{ height: this.state.dimensions.width / 3, width: this.state.dimensions.width / 3 }}
+ key={item.id}
+ onPress={() => this.onItemPressed(item)}>
+ <RkText style={styles.icon} rkType='primary moon xxlarge'>
+ {item.icon}
+ </RkText>
+ <RkText rkType='small'>{item.title}</RkText>
+ </RkButton>
+ );
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate(item.id);
+ };
+
+ render() {
+ const items = this.state.dimensions === undefined ? <View /> : this.renderItems();
+ return (
+ <ScrollView
+ style={styles.root}
+ onLayout={this.onContainerLayout}
+ contentContainerStyle={styles.rootContainer}>
+ {items}
+ </ScrollView>
+ );
+ }
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ rootContainer: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ },
+ empty: {
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ },
+ icon: {
+ marginBottom: 16,
+ },
+}));
diff --git a/frontend/app/screens/navigation/index.js b/frontend/app/screens/navigation/index.js
new file mode 100644
index 0000000..3f5229f
--- /dev/null
+++ b/frontend/app/screens/navigation/index.js
@@ -0,0 +1,4 @@
+export * from './grid2';
+export * from './grid';
+export * from './sideMenu';
+export * from './list';
diff --git a/frontend/app/screens/navigation/list.js b/frontend/app/screens/navigation/list.js
new file mode 100644
index 0000000..33c52ba
--- /dev/null
+++ b/frontend/app/screens/navigation/list.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import {
+ FlatList,
+ TouchableOpacity,
+ View,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkText,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { MainRoutes } from '../../config/navigation/routes';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class ListMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'List Menu'.toUpperCase(),
+ };
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate(item.id);
+ };
+
+ extractItemKey = (item) => item.id;
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity
+ style={styles.item}
+ onPress={() => this.onItemPressed(item)}>
+ <View style={styles.container}>
+ <RkText
+ style={styles.icon}
+ rkType='primary moon xxlarge'>{item.icon}
+ </RkText>
+ <RkText>{item.title}</RkText>
+ </View>
+ </TouchableOpacity>
+ );
+
+ render = () => (
+ <FlatList
+ style={styles.list}
+ data={MainRoutes}
+ keyExtractor={this.extractItemKey}
+ renderItem={this.renderItem}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ item: {
+ height: 80,
+ justifyContent: 'center',
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ paddingHorizontal: 16,
+ },
+ list: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ container: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ icon: {
+ width: 34,
+ textAlign: 'center',
+ marginRight: 16,
+ },
+}));
diff --git a/frontend/app/screens/navigation/sideMenu.js b/frontend/app/screens/navigation/sideMenu.js
new file mode 100644
index 0000000..7f5c5a1
--- /dev/null
+++ b/frontend/app/screens/navigation/sideMenu.js
@@ -0,0 +1,113 @@
+import React from 'react';
+import {
+ TouchableHighlight,
+ View,
+ ScrollView,
+ Image,
+ Platform,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkStyleSheet,
+ RkText,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import { MainRoutes } from '../../config/navigation/routes';
+import { FontAwesome, FontIcons } from '../../assets/icons';
+import NavigationType from '../../config/navigation/propTypes';
+import * as Screens from '../index';
+
+export const NavbarRoutes = [
+ {
+ id: 'Articles2',
+ title: 'Problems',
+ icon: FontIcons.article,
+ screen: Screens.Articles2,
+
+ }, {
+ id: 'Login1',
+ title: 'Login',
+ icon: FontIcons.login,
+ screen: Screens.LoginV1,
+
+ }, {
+ id: 'AddProblem',
+ title: 'Add Problem',
+ icon: FontIcons.article,
+ screen: Screens.AddToCardForm,
+
+ }];
+
+export class SideMenu extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+
+ onMenuItemPressed = (item) => {
+ this.props.navigation.navigate(item.id);
+ };
+
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/smallLogo.png') : require('../../assets/images/smallLogoDark.png')
+ );
+
+ renderIcon = () => (
+ <Image style={styles.icon} source={this.getThemeImageSource(RkTheme.current)}/>
+ );
+
+ renderMenu = () => NavbarRoutes.map(this.renderMenuItem);
+
+ renderMenuItem = (item) => (
+ <TouchableHighlight
+ style={styles.container}
+ key={item.id}
+ underlayColor={RkTheme.current.colors.button.underlay}
+ activeOpacity={1}
+ onPress={() => this.onMenuItemPressed(item)}>
+ <View style={styles.content}>
+ <View style={styles.content}>
+ <RkText
+ style={styles.icon}
+ rkType='moon primary xlarge'>{item.icon}
+ </RkText>
+ <RkText>{item.title}</RkText>
+ </View>
+ <RkText rkType='awesome secondaryColor small'>{FontAwesome.chevronRight}</RkText>
+ </View>
+ </TouchableHighlight>
+ );
+
+ render = () => (
+ <View style={styles.root}>
+ <ScrollView
+ showsVerticalScrollIndicator={false}>
+ <View style={[styles.container, styles.content]}>
+ <RkText rkType='logo'>EcoAlerts</RkText>
+ </View>
+ {this.renderMenu()}
+ </ScrollView>
+ </View>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ height: 80,
+ paddingHorizontal: 16,
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ },
+ root: {
+ paddingTop: Platform.OS === 'ios' ? 20 : 0,
+ backgroundColor: theme.colors.screen.base,
+ },
+ content: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ icon: {
+ marginRight: 13,
+ },
+}));
diff --git a/frontend/app/screens/other/index.js b/frontend/app/screens/other/index.js
new file mode 100644
index 0000000..9784f88
--- /dev/null
+++ b/frontend/app/screens/other/index.js
@@ -0,0 +1,2 @@
+export * from './splash';
+export * from './settings';
diff --git a/frontend/app/screens/other/settings.js b/frontend/app/screens/other/settings.js
new file mode 100644
index 0000000..910deb0
--- /dev/null
+++ b/frontend/app/screens/other/settings.js
@@ -0,0 +1,176 @@
+import React from 'react';
+import {
+ ScrollView,
+ View,
+ TouchableOpacity,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkText,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import {
+ RkSwitch,
+ FindFriends,
+} from '../../components';
+import { FontAwesome } from '../../assets/icons';
+
+export class Settings extends React.Component {
+ static navigationOptions = {
+ title: 'Settings'.toUpperCase(),
+ };
+
+ state = {
+ sendPush: true,
+ shouldRefresh: false,
+ twitterEnabled: true,
+ googleEnabled: false,
+ facebookEnabled: true,
+ };
+
+ onPushNotificationsSettingChanged = (value) => {
+ this.setState({ sendPush: value });
+ };
+
+ onRefreshAutomaticallySettingChanged = (value) => {
+ this.setState({ shouldRefresh: value });
+ };
+
+ onFindFriendsTwitterButtonPressed = () => {
+ this.setState({ twitterEnabled: !this.state.twitterEnabled });
+ };
+
+ onFindFriendsGoogleButtonPressed = () => {
+ this.setState({ googleEnabled: !this.state.googleEnabled });
+ };
+
+ onFindFriendsFacebookButtonPressed = () => {
+ this.setState({ facebookEnabled: !this.state.facebookEnabled });
+ };
+
+ render = () => (
+ <ScrollView style={styles.container}>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='primary header6'>PROFILE SETTINGS</RkText>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Edit Profile</RkText>
+ </TouchableOpacity>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Change Password</RkText>
+ </TouchableOpacity>
+ </View>
+ <View style={styles.row}>
+ <RkText rkType='header6'>Send Push Notifications</RkText>
+ <RkSwitch
+ style={styles.switch}
+ value={this.state.sendPush}
+ name="Push"
+ onValueChange={this.onPushNotificationsSettingChanged}
+ />
+ </View>
+ <View style={styles.row}>
+ <RkText rkType='header6'>Refresh Automatically</RkText>
+ <RkSwitch
+ style={styles.switch}
+ value={this.state.shouldRefresh}
+ name="Refresh"
+ onValueChange={this.onRefreshAutomaticallySettingChanged}
+ />
+ </View>
+ </View>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='primary header6'>FIND FRIENDS</RkText>
+ </View>
+ <View style={styles.row}>
+ <FindFriends
+ color={RkTheme.current.colors.twitter}
+ text='Twitter'
+ icon={FontAwesome.twitter}
+ selected={this.state.twitterEnabled}
+ onPress={this.onFindFriendsTwitterButtonPressed}
+ />
+ </View>
+ <View style={styles.row}>
+ <FindFriends
+ color={RkTheme.current.colors.google}
+ text='Google'
+ icon={FontAwesome.google}
+ selected={this.state.googleEnabled}
+ onPress={this.onFindFriendsGoogleButtonPressed}
+ />
+ </View>
+ <View style={styles.row}>
+ <FindFriends
+ color={RkTheme.current.colors.facebook}
+ text='Facebook'
+ icon={FontAwesome.facebook}
+ selected={this.state.facebookEnabled}
+ onPress={this.onFindFriendsFacebookButtonPressed}
+ />
+ </View>
+ </View>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='primary header6'>SUPPORT</RkText>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Help</RkText>
+ </TouchableOpacity>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Privacy Policy</RkText>
+ </TouchableOpacity>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Terms & Conditions</RkText>
+ </TouchableOpacity>
+ </View>
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.rowButton}>
+ <RkText rkType='header6'>Logout</RkText>
+ </TouchableOpacity>
+ </View>
+ </View>
+ </ScrollView>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ paddingVertical: 25,
+ },
+ section: {
+ marginVertical: 25,
+ },
+ heading: {
+ paddingBottom: 12.5,
+ },
+ row: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ paddingHorizontal: 17.5,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ alignItems: 'center',
+ },
+ rowButton: {
+ flex: 1,
+ paddingVertical: 24,
+ },
+ switch: {
+ marginVertical: 14,
+ },
+}));
diff --git a/frontend/app/screens/other/splash.js b/frontend/app/screens/other/splash.js
new file mode 100644
index 0000000..33e7abe
--- /dev/null
+++ b/frontend/app/screens/other/splash.js
@@ -0,0 +1,108 @@
+import React from 'react';
+import {
+ StyleSheet,
+ Image,
+ View,
+ Dimensions,
+ StatusBar,
+} from 'react-native';
+import {
+ RkText,
+ RkTheme,
+} from 'react-native-ui-kitten';
+import {
+ StackActions,
+ NavigationActions,
+} from 'react-navigation';
+import { ProgressBar } from '../../components';
+import { KittenTheme } from '../../config/theme';
+import { scale, scaleVertical } from '../../utils/scale';
+import NavigationType from '../../config/navigation/propTypes';
+
+const delay = 800;
+
+export class SplashScreen extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ state = {
+ progress: 0,
+ };
+
+ componentDidMount() {
+ StatusBar.setHidden(true, 'none');
+ RkTheme.setTheme(KittenTheme);
+ this.timer = setInterval(this.updateProgress, delay);
+ }
+
+ componentWillUnmount() {
+ clearInterval(this.timer);
+ }
+
+ updateProgress = () => {
+ if (this.state.progress === 1) {
+ clearInterval(this.timer);
+ setTimeout(this.onLoaded, delay);
+ } else {
+ const randProgress = this.state.progress + (Math.random() * 0.5);
+ this.setState({ progress: randProgress > 1 ? 1 : randProgress });
+ }
+ };
+
+ onLoaded = () => {
+ StatusBar.setHidden(false, 'slide');
+ const toHome = StackActions.reset({
+ index: 0,
+ actions: [NavigationActions.navigate({ routeName: 'Home' })],
+ });
+ this.props.navigation.dispatch(toHome);
+ };
+
+ render = () => (
+ <View style={styles.container}>
+ <View>
+ <Image
+ style={[styles.image, { width: Dimensions.get('window').width }]}
+ source={require('../../assets/images/splashBack.png')}
+ />
+ <View style={styles.text}>
+ <RkText rkType='light' style={styles.hero}>EcoAlerts</RkText>
+ <RkText rkType='logo' style={styles.appName}>The best ecological problems coordinator</RkText>
+ </View>
+ </View>
+ <ProgressBar
+ color={RkTheme.current.colors.accent}
+ style={styles.progress}
+ progress={this.state.progress}
+ width={scale(320)}
+ />
+ </View>
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ backgroundColor: KittenTheme.colors.screen.base,
+ justifyContent: 'space-between',
+ flex: 1,
+ },
+ image: {
+ resizeMode: 'cover',
+ height: scaleVertical(430),
+ },
+ text: {
+ alignItems: 'center',
+ },
+ hero: {
+ fontSize: 37,
+ },
+ appName: {
+ textAlign: 'center',
+ fontSize: 33,
+ },
+ progress: {
+ alignSelf: 'center',
+ marginBottom: 35,
+ backgroundColor: '#e5e5e5',
+ },
+});
diff --git a/frontend/app/screens/social/contacts.js b/frontend/app/screens/social/contacts.js
new file mode 100644
index 0000000..8eaacae
--- /dev/null
+++ b/frontend/app/screens/social/contacts.js
@@ -0,0 +1,124 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ StyleSheet,
+ TouchableOpacity,
+} from 'react-native';
+import _ from 'lodash';
+import {
+ RkStyleSheet,
+ RkText,
+ RkTextInput,
+} from 'react-native-ui-kitten';
+import { data } from '../../data';
+import { Avatar } from '../../components/avatar';
+import { FontAwesome } from '../../assets/icons';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class Contacts extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'Contacts'.toUpperCase(),
+ };
+
+ state = {
+ data: {
+ original: data.getUsers(),
+ filtered: data.getUsers(),
+ },
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ onSearchInputChanged = (event) => {
+ const pattern = new RegExp(event.nativeEvent.text, 'i');
+ const contacts = _.filter(this.state.data.original, contact => {
+ const filterResult = {
+ firstName: contact.firstName.search(pattern),
+ lastName: contact.lastName.search(pattern),
+ };
+ return filterResult.firstName !== -1 || filterResult.lastName !== -1 ? contact : undefined;
+ });
+ this.setState({
+ data: {
+ original: this.state.data.original,
+ filtered: contacts,
+ },
+ });
+ };
+
+ onItemPressed = (item) => {
+ this.props.navigation.navigate('ProfileV1', { id: item.id });
+ };
+
+ renderItem = ({ item }) => (
+ <TouchableOpacity onPress={() => this.onItemPressed(item)}>
+ <View style={styles.container}>
+ <Avatar rkType='circle' style={styles.avatar} img={item.photo} />
+ <RkText>{`${item.firstName} ${item.lastName}`}</RkText>
+ </View>
+ </TouchableOpacity>
+ );
+
+ renderSeparator = () => (
+ <View style={styles.separator} />
+ );
+
+ renderHeaderLabel = () => (
+ <RkText rkType='awesome'>{FontAwesome.search}</RkText>
+ );
+
+ renderHeader = () => (
+ <View style={styles.searchContainer}>
+ <RkTextInput
+ autoCapitalize='none'
+ autoCorrect={false}
+ onChange={this.onSearchInputChanged}
+ label={this.renderHeaderLabel()}
+ rkType='row'
+ placeholder='Search'
+ />
+ </View>
+ );
+
+ render = () => (
+ <FlatList
+ style={styles.root}
+ data={this.state.data.filtered}
+ renderItem={this.renderItem}
+ ListHeaderComponent={this.renderHeader}
+ ItemSeparatorComponent={this.renderSeparator}
+ keyExtractor={this.extractItemKey}
+ enableEmptySections
+ />
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ searchContainer: {
+ backgroundColor: theme.colors.screen.bold,
+ paddingHorizontal: 16,
+ paddingVertical: 10,
+ height: 60,
+ alignItems: 'center',
+ },
+ container: {
+ flexDirection: 'row',
+ padding: 16,
+ alignItems: 'center',
+ },
+ avatar: {
+ marginRight: 16,
+ },
+ separator: {
+ flex: 1,
+ height: StyleSheet.hairlineWidth,
+ backgroundColor: theme.colors.border.base,
+ },
+}));
diff --git a/frontend/app/screens/social/feed.js b/frontend/app/screens/social/feed.js
new file mode 100644
index 0000000..3de46f2
--- /dev/null
+++ b/frontend/app/screens/social/feed.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ Image,
+} from 'react-native';
+import {
+ RkCard,
+ RkText, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { Avatar } from '../../components/avatar';
+import { SocialBar } from '../../components/socialBar';
+import { data } from '../../data';
+
+const moment = require('moment');
+
+export class Feed extends React.Component {
+ static navigationOptions = {
+ title: 'Feed'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getArticles('post'),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ renderItem = ({ item }) => (
+ <RkCard style={styles.card}>
+ <View rkCardHeader>
+ <Avatar
+ rkType='small'
+ style={styles.avatar}
+ img={item.user.photo}
+ />
+ <View>
+ <RkText rkType='header4'>{`${item.user.firstName} ${item.user.lastName}`}</RkText>
+ <RkText rkType='secondary2 hintColor'>{moment().add(item.time, 'seconds').fromNow()}</RkText>
+ </View>
+ </View>
+ <Image rkCardImg source={item.photo} />
+ <View rkCardContent>
+ <RkText rkType='primary3'>{item.text}</RkText>
+ </View>
+ <View rkCardFooter>
+ <SocialBar />
+ </View >
+ </RkCard>
+ );
+
+ render = () => (
+ <FlatList
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ style={styles.container}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ container: {
+ backgroundColor: theme.colors.screen.scroll,
+ paddingVertical: 8,
+ paddingHorizontal: 10,
+ },
+ card: {
+ marginVertical: 8,
+ },
+ avatar: {
+ marginRight: 16,
+ },
+}));
diff --git a/frontend/app/screens/social/index.js b/frontend/app/screens/social/index.js
new file mode 100644
index 0000000..bd66176
--- /dev/null
+++ b/frontend/app/screens/social/index.js
@@ -0,0 +1,7 @@
+export * from './profile1';
+export * from './profile2';
+export * from './profile3';
+export * from './profileSettings';
+export * from './notifications';
+export * from './contacts';
+export * from './feed';
diff --git a/frontend/app/screens/social/notifications.js b/frontend/app/screens/social/notifications.js
new file mode 100644
index 0000000..c397d17
--- /dev/null
+++ b/frontend/app/screens/social/notifications.js
@@ -0,0 +1,98 @@
+import React from 'react';
+import {
+ FlatList,
+ View,
+ Image,
+} from 'react-native';
+import { RkStyleSheet, RkText } from 'react-native-ui-kitten';
+import { Avatar } from '../../components';
+import { data } from '../../data';
+
+const moment = require('moment');
+
+export class Notifications extends React.Component {
+ static navigationOptions = {
+ title: 'Notifications',
+ };
+
+ state = {
+ data: data.getNotifications(),
+ };
+
+ extractItemKey = (item) => `${item.id}`;
+
+ renderAttachment = (item) => {
+ const hasAttachment = item.attach !== undefined;
+ return hasAttachment ? <View /> : <Image style={styles.attachment} source={item.attach} />;
+ };
+
+ renderItem = ({ item }) => (
+ <View style={styles.container}>
+ <Avatar
+ img={item.user.photo}
+ rkType='circle'
+ style={styles.avatar}
+ badge={item.type}
+ />
+ <View style={styles.content}>
+ <View style={styles.mainContent}>
+ <View style={styles.text}>
+ <RkText>
+ <RkText rkType='header6'>{`${item.user.firstName} ${item.user.lastName}`}</RkText>
+ <RkText rkType='primary2'> {item.description}</RkText>
+ </RkText>
+ </View>
+ <RkText
+ rkType='secondary5 hintColor'>{moment().add(item.time, 'seconds').fromNow()}
+ </RkText>
+ </View>
+ {this.renderAttachment(item)}
+ </View>
+ </View>
+ );
+
+ render = () => (
+ <FlatList
+ style={styles.root}
+ data={this.state.data}
+ renderItem={this.renderItem}
+ keyExtractor={this.extractItemKey}
+ />
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ container: {
+ padding: 16,
+ flexDirection: 'row',
+ borderBottomWidth: 1,
+ borderColor: theme.colors.border.base,
+ alignItems: 'flex-start',
+ },
+ avatar: {},
+ text: {
+ marginBottom: 5,
+ },
+ content: {
+ flex: 1,
+ marginLeft: 16,
+ marginRight: 0,
+ },
+ mainContent: {
+ marginRight: 60,
+ },
+ img: {
+ height: 50,
+ width: 50,
+ margin: 0,
+ },
+ attachment: {
+ position: 'absolute',
+ right: 0,
+ height: 50,
+ width: 50,
+ },
+}));
diff --git a/frontend/app/screens/social/profile1.js b/frontend/app/screens/social/profile1.js
new file mode 100644
index 0000000..1f3ec09
--- /dev/null
+++ b/frontend/app/screens/social/profile1.js
@@ -0,0 +1,104 @@
+import React from 'react';
+import {
+ View,
+ ScrollView,
+} from 'react-native';
+import {
+ RkText,
+ RkButton, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { Avatar } from '../../components/avatar';
+import { Gallery } from '../../components/gallery';
+import { data } from '../../data/';
+import formatNumber from '../../utils/textUtils';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class ProfileV1 extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ title: 'User Profile'.toUpperCase(),
+ };
+
+ state = {
+ data: undefined,
+ };
+
+ constructor(props) {
+ super(props);
+ const id = this.props.navigation.getParam('id', 1);
+ this.state.data = data.getUser(id);
+ }
+
+ render = () => (
+ <ScrollView style={styles.root}>
+ <View style={[styles.header, styles.bordered]}>
+ <Avatar img={this.state.data.photo} rkType='big' />
+ <RkText rkType='header2'>{`${this.state.data.firstName} ${this.state.data.lastName}`}</RkText>
+ </View>
+ <View style={[styles.userInfo, styles.bordered]}>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.postCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Posts</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{formatNumber(this.state.data.followersCount)}</RkText>
+ <RkText rkType='secondary1 hintColor'>Followers</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.followingCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Following</RkText>
+ </View>
+ </View>
+ <View style={styles.buttons}>
+ <RkButton style={styles.button} rkType='clear link'>FOLLOW</RkButton>
+ <View style={styles.separator} />
+ <RkButton style={styles.button} rkType='clear link'>MESSAGE</RkButton>
+ </View>
+ <Gallery items={this.state.data.images} />
+ </ScrollView>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ alignItems: 'center',
+ paddingTop: 25,
+ paddingBottom: 17,
+ },
+ userInfo: {
+ flexDirection: 'row',
+ paddingVertical: 18,
+ },
+ bordered: {
+ borderBottomWidth: 1,
+ borderColor: theme.colors.border.base,
+ },
+ section: {
+ flex: 1,
+ alignItems: 'center',
+ },
+ space: {
+ marginBottom: 3,
+ },
+ separator: {
+ backgroundColor: theme.colors.border.base,
+ alignSelf: 'center',
+ flexDirection: 'row',
+ flex: 0,
+ width: 1,
+ height: 42,
+ },
+ buttons: {
+ flexDirection: 'row',
+ paddingVertical: 8,
+ },
+ button: {
+ flex: 1,
+ alignSelf: 'center',
+ },
+}));
diff --git a/frontend/app/screens/social/profile2.js b/frontend/app/screens/social/profile2.js
new file mode 100644
index 0000000..1636910
--- /dev/null
+++ b/frontend/app/screens/social/profile2.js
@@ -0,0 +1,108 @@
+import React from 'react';
+import {
+ View,
+ ScrollView,
+} from 'react-native';
+import {
+ RkText,
+ RkButton, RkStyleSheet,
+} from 'react-native-ui-kitten';
+import {
+ Avatar,
+ Gallery,
+} from '../../components';
+import { data } from '../../data';
+import { FontIcons } from '../../assets/icons';
+import formatNumber from '../../utils/textUtils';
+
+export class ProfileV2 extends React.Component {
+ static navigationOptions = {
+ title: 'User Profile'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getUser(),
+ };
+
+ render = () => (
+ <ScrollView style={styles.root}>
+ <View style={[styles.header, styles.bordered]}>
+ <View style={styles.row}>
+ <View style={styles.buttons}>
+ <RkButton style={styles.button} rkType='icon circle'>
+ <RkText rkType='moon large primary'>{FontIcons.profile}</RkText>
+ </RkButton>
+ </View>
+ <Avatar img={this.state.data.photo} rkType='big' />
+ <View style={styles.buttons}>
+ <RkButton style={styles.button} rkType='icon circle'>
+ <RkText rkType='moon large primary'>{FontIcons.mail}</RkText>
+ </RkButton>
+ </View>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header2'>{`${this.state.data.firstName} ${this.state.data.lastName}`}</RkText>
+ </View>
+ </View>
+ <View style={styles.userInfo}>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.postCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Posts</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{formatNumber(this.state.data.followersCount)}</RkText>
+ <RkText rkType='secondary1 hintColor'>Followers</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.followingCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Following</RkText>
+ </View>
+ </View>
+ <Gallery items={this.state.data.images} />
+ </ScrollView>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ paddingTop: 25,
+ paddingBottom: 17,
+ },
+ row: {
+ flexDirection: 'row',
+
+ },
+ userInfo: {
+ flexDirection: 'row',
+ paddingVertical: 18,
+ },
+ bordered: {
+ borderBottomWidth: 1,
+ borderColor: theme.colors.border.base,
+ },
+ section: {
+ flex: 1,
+ alignItems: 'center',
+ },
+ space: {
+ marginBottom: 3,
+ },
+ separator: {
+ backgroundColor: theme.colors.border.base,
+ alignSelf: 'center',
+ flexDirection: 'row',
+ flex: 0,
+ width: 1,
+ height: 42,
+ },
+ buttons: {
+ flex: 1,
+ },
+ button: {
+ marginTop: 27.5,
+ alignSelf: 'center',
+ },
+}));
diff --git a/frontend/app/screens/social/profile3.js b/frontend/app/screens/social/profile3.js
new file mode 100644
index 0000000..985dc1e
--- /dev/null
+++ b/frontend/app/screens/social/profile3.js
@@ -0,0 +1,96 @@
+import React from 'react';
+import {
+ View,
+ ScrollView,
+} from 'react-native';
+import {
+ RkStyleSheet,
+ RkText,
+} from 'react-native-ui-kitten';
+import {
+ Avatar,
+ Gallery,
+ GradientButton,
+} from '../../components';
+import { data } from '../../data';
+import formatNumber from '../../utils/textUtils';
+
+export class ProfileV3 extends React.Component {
+ static navigationOptions = {
+ title: 'User Profile'.toUpperCase(),
+ };
+
+ state = {
+ data: data.getUser(),
+ };
+
+ render = () => (
+ <ScrollView style={styles.root}>
+ <View style={[styles.header, styles.bordered]}>
+ <Avatar img={this.state.data.photo} rkType='big' />
+ <RkText rkType='header2'>{`${this.state.data.firstName} ${this.state.data.lastName}`}</RkText>
+ <GradientButton style={styles.button} text='FOLLOW' />
+ </View>
+
+ <View style={styles.userInfo}>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.postCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Posts</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{formatNumber(this.state.data.followersCount)}</RkText>
+ <RkText rkType='secondary1 hintColor'>Followers</RkText>
+ </View>
+ <View style={styles.section}>
+ <RkText rkType='header3' style={styles.space}>{this.state.data.followingCount}</RkText>
+ <RkText rkType='secondary1 hintColor'>Following</RkText>
+ </View>
+ </View>
+ <Gallery items={this.state.data.images} />
+ </ScrollView>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ alignItems: 'center',
+ paddingTop: 25,
+ paddingBottom: 17,
+ },
+ userInfo: {
+ flexDirection: 'row',
+ paddingVertical: 18,
+ },
+ bordered: {
+ borderBottomWidth: 1,
+ borderColor: theme.colors.border.base,
+ },
+ section: {
+ flex: 1,
+ alignItems: 'center',
+ },
+ space: {
+ marginBottom: 3,
+ },
+ separator: {
+ backgroundColor: theme.colors.border.base,
+ alignSelf: 'center',
+ flexDirection: 'row',
+ flex: 0,
+ width: 1,
+ height: 42,
+ },
+ buttons: {
+ flexDirection: 'row',
+ paddingVertical: 8,
+ },
+ button: {
+ marginTop: 18,
+ alignSelf: 'center',
+ width: 140,
+ },
+
+}));
diff --git a/frontend/app/screens/social/profileSettings.js b/frontend/app/screens/social/profileSettings.js
new file mode 100644
index 0000000..0be1b94
--- /dev/null
+++ b/frontend/app/screens/social/profileSettings.js
@@ -0,0 +1,200 @@
+import React from 'react';
+import {
+ ScrollView,
+ View,
+ StyleSheet,
+} from 'react-native';
+import {
+ RkText,
+ RkTextInput,
+ RkAvoidKeyboard,
+ RkTheme,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { data } from '../../data';
+import {
+ Avatar,
+ SocialSetting,
+ GradientButton,
+} from '../../components';
+import { FontAwesome } from '../../assets/icons';
+
+export class ProfileSettings extends React.Component {
+ static navigationOptions = {
+ title: 'Profile Settings'.toUpperCase(),
+ };
+
+ user = data.getUser();
+
+ state = {
+ firstName: this.user.firstName,
+ lastName: this.user.lastName,
+ email: this.user.email,
+ country: this.user.country,
+ phone: this.user.phone,
+ password: this.user.password,
+ newPassword: this.user.newPassword,
+ confirmPassword: this.user.confirmPassword,
+ };
+
+ onFirstNameInputChanged = (text) => {
+ this.setState({ firstName: text });
+ };
+
+ onLastNameInputChanged = (text) => {
+ this.setState({ lastName: text });
+ };
+
+ onEmailInputChanged = (text) => {
+ this.setState({ email: text });
+ };
+
+ onCountryInputChanged = (text) => {
+ this.setState({ country: text });
+ };
+
+ onPhoneInputChanged = (text) => {
+ this.setState({ phone: text });
+ };
+
+ onPasswordInputChanged = (text) => {
+ this.setState({ password: text });
+ };
+
+ onNewPasswordInputChanged = (text) => {
+ this.setState({ newPassword: text });
+ };
+
+ onConfirmPasswordInputChanged = (text) => {
+ this.setState({ confirmPassword: text });
+ };
+
+ render = () => (
+ <ScrollView style={styles.root}>
+ <RkAvoidKeyboard>
+ <View style={styles.header}>
+ <Avatar img={this.user.photo} rkType='big' />
+ </View>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='header6 primary'>INFO</RkText>
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='First Name'
+ value={this.state.firstName}
+ rkType='right clear'
+ onChangeText={this.onFirstNameInputChanged}
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Last Name'
+ value={this.state.lastName}
+ onChangeText={this.onLastNameInputChanged}
+ rkType='right clear'
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Email'
+ value={this.state.email}
+ onChangeText={this.onEmailInputChanged}
+ rkType='right clear'
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Country'
+ value={this.state.country}
+ onChangeText={this.onCountryInputChanged}
+ rkType='right clear'
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Phone'
+ value={this.state.phone}
+ onChangeText={this.onPhoneInputChanged}
+ rkType='right clear'
+ />
+ </View>
+ </View>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='primary header6'>CHANGE PASSWORD</RkText>
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Old Password'
+ value={this.state.password}
+ rkType='right clear'
+ secureTextEntry
+ onChangeText={this.onPasswordInputChanged}
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='New Password'
+ value={this.state.newPassword}
+ rkType='right clear'
+ secureTextEntry
+ onChangeText={this.onNewPasswordInputChanged}
+ />
+ </View>
+ <View style={styles.row}>
+ <RkTextInput
+ label='Confirm Password'
+ value={this.state.confirmPassword}
+ rkType='right clear'
+ secureTextEntry
+ onChangeText={this.onConfirmPasswordInputChanged}
+ />
+ </View>
+ </View>
+ <View style={styles.section}>
+ <View style={[styles.row, styles.heading]}>
+ <RkText rkType='primary header6'>CONNECT YOUR ACCOUNT</RkText>
+ </View>
+ <View style={styles.row}>
+ <SocialSetting name='Twitter' icon={FontAwesome.twitter} tintColor={RkTheme.current.colors.twitter} />
+ </View>
+ <View style={styles.row}>
+ <SocialSetting name='Google' icon={FontAwesome.google} tintColor={RkTheme.current.colors.google} />
+ </View>
+ <View style={styles.row}>
+ <SocialSetting name='Facebook' icon={FontAwesome.facebook} tintColor={RkTheme.current.colors.facebook} />
+ </View>
+ </View>
+ <GradientButton rkType='large' style={styles.button} text='SAVE' />
+ </RkAvoidKeyboard>
+ </ScrollView>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ },
+ header: {
+ backgroundColor: theme.colors.screen.neutral,
+ paddingVertical: 25,
+ },
+ section: {
+ marginVertical: 25,
+ },
+ heading: {
+ paddingBottom: 12.5,
+ },
+ row: {
+ flexDirection: 'row',
+ paddingHorizontal: 17.5,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderColor: theme.colors.border.base,
+ alignItems: 'center',
+ },
+ button: {
+ marginHorizontal: 16,
+ marginBottom: 32,
+ },
+}));
diff --git a/frontend/app/screens/theme/index.js b/frontend/app/screens/theme/index.js
new file mode 100644
index 0000000..22cacb2
--- /dev/null
+++ b/frontend/app/screens/theme/index.js
@@ -0,0 +1 @@
+export * from './themes';
diff --git a/frontend/app/screens/theme/themes.js b/frontend/app/screens/theme/themes.js
new file mode 100644
index 0000000..82f4165
--- /dev/null
+++ b/frontend/app/screens/theme/themes.js
@@ -0,0 +1,77 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ StatusBar,
+ Platform,
+} from 'react-native';
+import {
+ RkText,
+ RkTheme,
+ RkStyleSheet,
+} from 'react-native-ui-kitten';
+import { DarkKittenTheme } from '../../config/darkTheme';
+import { KittenTheme } from '../../config/theme';
+import { GradientButton } from '../../components/gradientButton';
+import { scale, scaleVertical } from '../../utils/scale';
+
+export class Themes extends React.Component {
+ static navigationOptions = {
+ title: 'Theme'.toUpperCase(),
+ };
+
+ onLightThemeApplyButtonPressed = () => {
+ StatusBar.setBarStyle('dark-content', true);
+ if (Platform.OS === 'android') {
+ StatusBar.setBackgroundColor(KittenTheme.colors.screen.base);
+ }
+ RkTheme.setTheme(KittenTheme);
+ };
+
+ onDarkThemeApplyButtonPressed = () => {
+ StatusBar.setBarStyle('light-content', true);
+ if (Platform.OS === 'android') {
+ StatusBar.setBackgroundColor(DarkKittenTheme.colors.screen.base);
+ }
+ RkTheme.setTheme(DarkKittenTheme);
+ };
+
+ render = () => (
+ <View style={styles.root}>
+ <View style={styles.container}>
+ <RkText>Light Theme</RkText>
+ <Image style={styles.image} source={require('../../assets/images/lightThemeImage.png')} />
+ <GradientButton
+ text='APPLY'
+ onPress={this.onLightThemeApplyButtonPressed}
+ />
+ </View>
+ <View style={styles.container}>
+ <RkText>Dark Theme</RkText>
+ <Image style={styles.image} source={require('../../assets/images/darkThemeImage.png')} />
+ <GradientButton
+ text='APPLY'
+ onPress={this.onDarkThemeApplyButtonPressed}
+ />
+ </View>
+ </View>
+ );
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ root: {
+ backgroundColor: theme.colors.screen.base,
+ flex: 1,
+ paddingHorizontal: scale(72),
+
+ },
+ image: {
+ height: scaleVertical(160),
+ },
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ paddingVertical: scaleVertical(20),
+ },
+}));
diff --git a/frontend/app/screens/walkthroughs/index.js b/frontend/app/screens/walkthroughs/index.js
new file mode 100644
index 0000000..e7f1eb0
--- /dev/null
+++ b/frontend/app/screens/walkthroughs/index.js
@@ -0,0 +1 @@
+export * from './walkthroughScreen';
diff --git a/frontend/app/screens/walkthroughs/walkthrough1.js b/frontend/app/screens/walkthroughs/walkthrough1.js
new file mode 100644
index 0000000..2f08f97
--- /dev/null
+++ b/frontend/app/screens/walkthroughs/walkthrough1.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import {
+ View,
+ Image,
+} from 'react-native';
+import {
+ RkText,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+
+export class Walkthrough1 extends React.Component {
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/kittenImage.png') : require('../../assets/images/kittenImageDark.png')
+ );
+
+ renderImage = () => (
+ <Image source={this.getThemeImageSource(RkTheme.current)} />
+ );
+
+ render = () => (
+ <View style={styles.screen}>
+ {this.renderImage()}
+ <RkText rkType='header2' style={styles.text}>Welcome to EcoAlerts</RkText>
+ </View>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ backgroundColor: theme.colors.screen.base,
+ alignItems: 'center',
+ justifyContent: 'center',
+ flex: 1,
+ },
+ text: {
+ marginTop: 20,
+ },
+}));
diff --git a/frontend/app/screens/walkthroughs/walkthrough2.js b/frontend/app/screens/walkthroughs/walkthrough2.js
new file mode 100644
index 0000000..6e387b8
--- /dev/null
+++ b/frontend/app/screens/walkthroughs/walkthrough2.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import {
+ View,
+ Image,
+ Dimensions,
+} from 'react-native';
+import {
+ RkText,
+ RkStyleSheet,
+ RkTheme,
+} from 'react-native-ui-kitten';
+
+export class Walkthrough2 extends React.Component {
+ getThemeImageSource = (theme) => (
+ theme.name === 'light' ?
+ require('../../assets/images/screensImage.png') : require('../../assets/images/screensImageDark.png')
+ );
+
+ renderImage = () => (
+ <Image
+ style={{ width: Dimensions.get('window').width }}
+ source={this.getThemeImageSource(RkTheme.current)}
+ />
+ );
+
+ render = () => (
+ <View style={styles.screen}>
+ {this.renderImage()}
+ <RkText rkType='header2' style={styles.text}>Share info about ecological problems around!</RkText>
+ </View>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ backgroundColor: theme.colors.screen.base,
+ alignItems: 'center',
+ justifyContent: 'center',
+ flex: 1,
+ },
+ text: {
+ textAlign: 'center',
+ marginTop: 20,
+ marginHorizontal: 30,
+ },
+}));
diff --git a/frontend/app/screens/walkthroughs/walkthroughScreen.js b/frontend/app/screens/walkthroughs/walkthroughScreen.js
new file mode 100644
index 0000000..f0c21b5
--- /dev/null
+++ b/frontend/app/screens/walkthroughs/walkthroughScreen.js
@@ -0,0 +1,61 @@
+import React from 'react';
+import { View } from 'react-native';
+import { RkStyleSheet } from 'react-native-ui-kitten';
+import {
+ GradientButton,
+ PaginationIndicator,
+} from '../../components/';
+import { Walkthrough } from '../../components/walkthrough';
+import { Walkthrough1 } from './walkthrough1';
+import { Walkthrough2 } from './walkthrough2';
+import NavigationType from '../../config/navigation/propTypes';
+
+export class WalkthroughScreen extends React.Component {
+ static propTypes = {
+ navigation: NavigationType.isRequired,
+ };
+ static navigationOptions = {
+ header: null,
+ };
+
+ state = {
+ index: 0,
+ };
+
+ onWalkThroughIndexChanged = (index) => {
+ this.setState({ index });
+ };
+
+ onStartButtonPressed = () => {
+ this.props.navigation.navigate('Articles2');
+ };
+
+ render = () => (
+ <View style={styles.screen}>
+ <Walkthrough onChanged={this.onWalkThroughIndexChanged}>
+ <Walkthrough1 />
+ <Walkthrough2 />
+ </Walkthrough>
+ <PaginationIndicator length={2} current={this.state.index} />
+ <GradientButton
+ rkType='large'
+ style={styles.button}
+ text="GET STARTED"
+ onPress={this.onStartButtonPressed}
+ />
+ </View>
+ )
+}
+
+const styles = RkStyleSheet.create(theme => ({
+ screen: {
+ backgroundColor: theme.colors.screen.base,
+ paddingVertical: 28,
+ alignItems: 'center',
+ flex: 1,
+ },
+ button: {
+ marginTop: 25,
+ marginHorizontal: 16,
+ },
+}));