diff --git a/App.js b/App.js
index 8d541bb..86f0a66 100644
--- a/App.js
+++ b/App.js
@@ -1,6 +1,8 @@
import React from "react";
import { Asset, AppLoading, Font, Updates } from "expo";
-import { Platform } from "react-native";
+import { AsyncStorage, Alert, Platform, View } from "react-native";
+import ApolloClient from "apollo-boost";
+import { ApolloProvider } from "react-apollo";
import { Ionicons } from "@expo/vector-icons";
import { loadSavedTalksAsync } from "./src/utils/storage";
import { SafeAreaView } from "react-navigation";
@@ -9,6 +11,10 @@ if (Platform.OS === "android") {
SafeAreaView.setStatusBarHeight(0);
}
+const client = new ApolloClient({
+ uri: "https://www.react-europe.org/gql"
+});
+
import Navigation from "./src/Navigation";
export default class App extends React.Component {
@@ -84,6 +90,10 @@ export default class App extends React.Component {
);
}
- return ;
+ return (
+
+
+
+ );
}
}
diff --git a/package.json b/package.json
index c701553..667f5f0 100644
--- a/package.json
+++ b/package.json
@@ -10,10 +10,13 @@
"lint": "eslint . --ext .js --quiet"
},
"dependencies": {
+ "apollo-boost": "^0.1.6",
"crypto-js": "^3.1.9-1",
"expo": "^27.0.0",
"fbemitter": "^2.1.1",
"global": "^4.3.2",
+ "graphql": "^0.13.2",
+ "graphql-tag": "^2.9.2",
"hoist-non-react-statics": "^2.3.1",
"lodash": "^4.17.4",
"moment": "2.21.0",
@@ -21,6 +24,7 @@
"path": "^0.12.7",
"prettier": "^1.11.1",
"react": "16.3.1",
+ "react-apollo": "^2.1.4",
"react-native": "https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz",
"react-native-animatable": "^1.2.4",
"react-native-fade-in-image": "1.3.0",
diff --git a/src/Navigation.js b/src/Navigation.js
index 6616d9b..a8b289b 100644
--- a/src/Navigation.js
+++ b/src/Navigation.js
@@ -1,14 +1,14 @@
-import React from 'react';
-import PropTypes from 'prop-types';
+import React from "react";
+import PropTypes from "prop-types";
import {
TabRouter,
TabNavigator,
StackNavigator,
createNavigator,
- createNavigationContainer,
-} from 'react-navigation';
-import withCachedChildNavigation from 'react-navigation/src/withCachedChildNavigation';
-import SceneView from 'react-navigation/src/views/SceneView';
+ createNavigationContainer
+} from "react-navigation";
+import withCachedChildNavigation from "react-navigation/src/withCachedChildNavigation";
+import SceneView from "react-navigation/src/views/SceneView";
import {
BackHandler,
Platform,
@@ -16,54 +16,51 @@ import {
StyleSheet,
StatusBar,
View
-} from 'react-native';
-import { Constants } from 'expo';
-import { TabViewAnimated } from 'react-native-tab-view';
-import {
- DrawerLayoutAndroid,
- RectButton,
-} from 'react-native-gesture-handler';
-import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
-import ResourceSavingContainer from 'react-native-resource-saving-container';
-import hoistStatics from 'hoist-non-react-statics';
-
-import { Colors, FontSizes, Layout } from './constants';
-import Screens from './screens';
-import TabBarBottom from './components/TabBarBottom';
-import CachedImage from './components/CachedImage';
-import { SemiBoldText } from './components/StyledText';
-import _ from 'lodash';
-import Schedule from './data/schedule.json';
-import moment from 'moment';
-
-import QRScannerModalNavigation from './screens/QRScreens/Identify';
-import QRCheckinScannerModalNavigation from './screens/QRScreens/CheckIn';
-import QRContactScannerModalNavigation from './screens/QRScreens/Contact';
+} from "react-native";
+import { Constants } from "expo";
+import { TabViewAnimated } from "react-native-tab-view";
+import { DrawerLayoutAndroid, RectButton } from "react-native-gesture-handler";
+import DrawerLayout from "react-native-gesture-handler/DrawerLayout";
+import ResourceSavingContainer from "react-native-resource-saving-container";
+import hoistStatics from "hoist-non-react-statics";
+
+import { Colors, FontSizes, Layout } from "./constants";
+import Screens from "./screens";
+import TabBarBottom from "./components/TabBarBottom";
+import CachedImage from "./components/CachedImage";
+import { SemiBoldText } from "./components/StyledText";
+import _ from "lodash";
+import Schedule from "./data/schedule.json";
+import moment from "moment";
+
+import QRScannerModalNavigation from "./screens/QRScreens/Identify";
+import QRCheckinScannerModalNavigation from "./screens/QRScreens/CheckIn";
+import QRContactScannerModalNavigation from "./screens/QRScreens/Contact";
const DrawerComponent =
- Platform.OS === 'android' ? DrawerLayoutAndroid : DrawerLayout;
+ Platform.OS === "android" ? DrawerLayoutAndroid : DrawerLayout;
const FullSchedule = Schedule.events[0].groupedSchedule;
let navSchedule = {};
-_.each(FullSchedule, (day) => {
+_.each(FullSchedule, day => {
navSchedule[day.title] = {
screen: Screens.ScheduleDay({
day: day.title,
- date: moment(new Date(day.date)).format('D'),
- }),
+ date: moment(new Date(day.date)).format("D")
+ })
};
});
const ScheduleNavigation = TabNavigator(navSchedule, {
- initialRouteName: moment().format('dddd'),
+ initialRouteName: moment().format("dddd"),
lazy: true,
swipeEnabled: false,
animationEnabled: false,
tabBarComponent: TabBarBottom,
- tabBarPosition: 'bottom',
+ tabBarPosition: "bottom",
tabBarOptions: {
- style: { backgroundColor: '#333' },
- activeTintColor: '#fff',
- },
+ style: { backgroundColor: "#333" },
+ activeTintColor: "#fff"
+ }
});
export function connectDrawerButton(WrappedComponent) {
@@ -81,7 +78,7 @@ export function connectDrawerButton(WrappedComponent) {
ConnectedDrawerButton.contextTypes = {
openDrawer: PropTypes.func,
closeDrawer: PropTypes.func,
- toggleDrawer: PropTypes.func,
+ toggleDrawer: PropTypes.func
};
return hoistStatics(ConnectedDrawerButton, WrappedComponent);
@@ -89,15 +86,15 @@ export function connectDrawerButton(WrappedComponent) {
const DefaultStackConfig = {
cardStyle: {
- backgroundColor: '#fafafa',
- },
+ backgroundColor: "#fafafa"
+ }
};
const SpeakersNavigation = StackNavigator(
{
SpeakerList: {
- screen: Screens.Speakers,
- },
+ screen: Screens.Speakers
+ }
},
DefaultStackConfig
);
@@ -105,8 +102,17 @@ const SpeakersNavigation = StackNavigator(
const CrewNavigation = StackNavigator(
{
CrewList: {
- screen: Screens.Crew,
- },
+ screen: Screens.Crew
+ }
+ },
+ DefaultStackConfig
+);
+
+const AttendeesNavigation = StackNavigator(
+ {
+ AttendeeList: {
+ screen: Screens.Attendees
+ }
},
DefaultStackConfig
);
@@ -114,8 +120,8 @@ const CrewNavigation = StackNavigator(
const SponsorNavigation = StackNavigator(
{
SponsorList: {
- screen: Screens.Sponsors,
- },
+ screen: Screens.Sponsors
+ }
},
DefaultStackConfig
);
@@ -123,8 +129,8 @@ const SponsorNavigation = StackNavigator(
const StaffCheckinListsNavigation = StackNavigator(
{
StaffCheckinListsList: {
- screen: Screens.StaffCheckinLists,
- },
+ screen: Screens.StaffCheckinLists
+ }
},
DefaultStackConfig
);
@@ -133,11 +139,12 @@ const DrawerRouteConfig = {
Home: { screen: Screens.Home },
Schedule: { screen: ScheduleNavigation },
Speakers: { screen: SpeakersNavigation },
+ Attendees: { screen: AttendeesNavigation },
Crew: { screen: CrewNavigation },
Sponsors: { screen: SponsorNavigation },
Profile: { screen: Screens.Profile },
Contacts: { screen: Screens.Contacts },
- StaffCheckinLists: { screen: StaffCheckinListsNavigation },
+ StaffCheckinLists: { screen: StaffCheckinListsNavigation }
};
const DrawerRouter = TabRouter(DrawerRouteConfig);
@@ -145,7 +152,7 @@ const DrawerRouter = TabRouter(DrawerRouteConfig);
class DrawerScene extends React.PureComponent {
state = {
visible: true,
- me: null,
+ me: null
};
setVisible = visible => {
@@ -161,8 +168,9 @@ class DrawerScene extends React.PureComponent {
return (
+ style={{ flex: 1, overflow: "hidden" }}
+ visible={Platform.OS === "android" ? this.state.visible : true}
+ >
{
@@ -232,9 +240,8 @@ class DrawerView extends React.Component {
const nextIndex = nextProps.navigation.state.index;
const nextRoute = nextProps.navigation.state.routes[nextIndex];
-
if (!this.state.loaded.includes(nextProps.navigation.state.index)) {
- this.setState({loaded: [...this.state.loaded, nextIndex]});
+ this.setState({ loaded: [...this.state.loaded, nextIndex] });
}
if (currentRoute.key !== nextRoute.key) {
@@ -278,15 +285,17 @@ class DrawerView extends React.Component {
drawerPosition={DrawerComponent.positions.Left}
drawerType="front"
drawerBackgroundColor="#333333"
- renderNavigationView={this._renderNavigationView}>
+ renderNavigationView={this._renderNavigationView}
+ >
+ Platform.OS === "android" ? Constants.statusBarHeight : 0
+ }}
+ >
@@ -320,34 +329,35 @@ class DrawerView extends React.Component {
+ alignItems: "center",
+ justifyContent: "center",
+ paddingTop: Layout.notchHeight + 20
+ }
+ ]}
+ >
@@ -355,18 +365,19 @@ class DrawerView extends React.Component {
{/* make sure the buttons here are in the same order as in route config */}
{this._renderButtons([
- { route: 'Home', title: 'Home' },
- { route: 'Schedule', title: 'Schedule' },
- { route: 'Speakers', title: 'Speakers' },
- { route: 'Crew', title: 'Crew' },
- { route: 'Sponsors', title: 'Sponsors' },
- { route: 'Profile', title: 'Profile' },
- { route: 'Contacts', title: 'Contacts' },
+ { route: "Home", title: "Home" },
+ { route: "Schedule", title: "Schedule" },
+ { route: "Speakers", title: "Speakers" },
+ { route: "Attendees", title: "Attendees" },
+ { route: "Crew", title: "Crew" },
+ { route: "Sponsors", title: "Sponsors" },
+ { route: "Profile", title: "Profile" },
+ { route: "Contacts", title: "Contacts" },
{
- route: 'StaffCheckinLists',
- title: 'StaffCheckinLists',
- hidden: true,
- },
+ route: "StaffCheckinLists",
+ title: "StaffCheckinLists",
+ hidden: true
+ }
])}
@@ -382,7 +393,8 @@ class DrawerView extends React.Component {
this._navigateToScreen(i)}
- selected={selectedIndex === i}>
+ selected={selectedIndex === i}
+ >
{config.title}
)
@@ -416,7 +428,7 @@ const DrawerNavigation = createNavigationContainer(
class DrawerButton extends React.Component {
state = {
- me: null,
+ me: null
};
render() {
return (
@@ -424,16 +436,18 @@ class DrawerButton extends React.Component {
onPress={this.props.onPress}
style={{
backgroundColor: this.props.selected
- ? 'rgba(255,255,255,0.1)'
- : '#333333',
- }}>
+ ? "rgba(255,255,255,0.1)"
+ : "#333333"
+ }}
+ >
+ justifyContent: "center",
+ paddingHorizontal: 5
+ }}
+ >
{this.props.children.toUpperCase()}
@@ -445,32 +459,33 @@ class DrawerButton extends React.Component {
const styles = StyleSheet.create({
container: {
- flex: 1,
+ flex: 1
},
drawerButtonText: {
- color: '#fff',
+ color: "#fff",
fontSize: FontSizes.normalButton,
- padding: 10,
+ padding: 10
},
drawerButtons: {
- paddingTop: 0,
+ paddingTop: 0
},
- drawerNavigationContainer: {},
+ drawerNavigationContainer: {}
});
export default StackNavigator(
{
Primary: { screen: DrawerNavigation },
Details: { screen: Screens.Details },
+ AttendeeDetails: { screen: Screens.AttendeeDetails },
TicketInstructions: { screen: Screens.TicketInstructions },
CheckedInAttendeeInfo: { screen: Screens.CheckedInAttendeeInfo },
QRScanner: { screen: QRScannerModalNavigation },
QRCheckinScanner: { screen: QRCheckinScannerModalNavigation },
- QRContactScanner: { screen: QRContactScannerModalNavigation },
+ QRContactScanner: { screen: QRContactScannerModalNavigation }
},
{
...DefaultStackConfig,
- headerMode: 'none',
- mode: 'modal',
+ headerMode: "none",
+ mode: "modal"
}
);
diff --git a/src/components/SearchAttendeeListItem.js b/src/components/SearchAttendeeListItem.js
new file mode 100644
index 0000000..f76417a
--- /dev/null
+++ b/src/components/SearchAttendeeListItem.js
@@ -0,0 +1,59 @@
+import React from "react";
+import { Image, Platform, StyleSheet, View, Linking } from "react-native";
+import { Svg, FileSystem, WebBrowser } from "expo";
+import { RectButton } from "react-native-gesture-handler";
+import FadeIn from "react-native-fade-in-image";
+import { withNavigation } from "react-navigation";
+import GravatarImage from "../components/GravatarImage";
+import SaveIconWhenSaved from "./SaveIconWhenSaved";
+import { BoldText, RegularText, SemiBoldText } from "./StyledText";
+import { conferenceHasEnded, getSpeakerAvatarURL } from "../utils";
+import { Colors, FontSizes } from "../constants";
+
+import {
+ Card,
+ CardActions,
+ CardContent,
+ Title,
+ Paragraph
+} from "react-native-paper";
+
+//@withNavigation
+export default class SearchAttendeeListItem extends React.Component {
+ render() {
+ const { contact, onPress } = this.props;
+ const { firstName, lastName, email } = contact;
+
+ return (
+ onPress(contact)}
+ activeOpacity={0.05}
+ style={{ flex: 1, backgroundColor: "#fff" }}
+ >
+
+
+
+ {firstName + " " + lastName}
+
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ avatarImage: {
+ width: 64,
+ height: 64,
+ borderRadius: 32,
+ marginLeft: 8,
+ marginTop: 8
+ },
+ listItemTitle: {
+ flex: 1,
+ height: 64,
+ justifyContent: "center",
+ marginLeft: 8,
+ marginTop: 8
+ }
+});
diff --git a/src/components/SearchAttendees.js b/src/components/SearchAttendees.js
new file mode 100644
index 0000000..8ba6064
--- /dev/null
+++ b/src/components/SearchAttendees.js
@@ -0,0 +1,124 @@
+import React from "react";
+import {
+ Image,
+ Platform,
+ StyleSheet,
+ View,
+ AsyncStorage,
+ TextInput,
+ FlatList
+} from "react-native";
+import moment from "moment-timezone";
+import { ApolloConsumer } from "react-apollo";
+import gql from "graphql-tag";
+import _ from "lodash";
+import { Searchbar } from "react-native-paper";
+import { BoldText, RegularText, SemiBoldText } from "./StyledText";
+import SearchAttendeeListItem from "./SearchAttendeeListItem";
+import { Colors, FontSizes } from "../constants";
+
+export default class SearchAttendeesInput extends React.Component {
+ constructor(props) {
+ super(props);
+ this.onChangeTextDelayed = _.debounce(this.onChangeText, 500);
+ this.state = {
+ text: "",
+ attendees: [],
+ loading: false
+ };
+ }
+
+ async onChangeText(text, client) {
+ const { uuid } = this.props;
+ if (!this.state.loading) {
+ this.setState({ loading: true });
+
+ try {
+ const { data } = await client.query({
+ query: ATTENDEE_SEARCH_QUERY,
+ variables: {
+ slug: "reacteurope-2018",
+ q: text,
+ uuid
+ }
+ });
+
+ const event =
+ data && data.events && data.events.length > 0 && data.events[0];
+
+ let attendees;
+ if (!event) {
+ attendees = [];
+ } else {
+ attendees = event.attendees ? event.attendees : [];
+ }
+ this.setState({ attendees, loading: false });
+ } catch (err) {
+ this.setState({ loading: false });
+ }
+ }
+ }
+
+ render() {
+ const { attendees } = this.state;
+ const { onPressAttendee } = this.props;
+ return (
+
+ {client => (
+
+
+
+ Search Attendees
+
+ this.onChangeTextDelayed(query, client)}
+ />
+
+
+ String(item.id)}
+ renderItem={({ item, index }) => {
+ return (
+ {
+ onPressAttendee(attendee);
+ }}
+ />
+ );
+ }}
+ />
+
+ )}
+
+ );
+ }
+}
+
+//
+const ATTENDEE_SEARCH_QUERY = gql`
+ query attendeeSearch($slug: String, $q: String!, $uuid: String!) {
+ events(slug: $slug) {
+ attendees(q: $q, uuid: $uuid) {
+ id
+ lastName
+ email
+ firstName
+ answers {
+ id
+ value
+ question {
+ id
+ title
+ }
+ }
+ }
+ }
+ }
+`;
diff --git a/src/screens/AttendeeDetails.js b/src/screens/AttendeeDetails.js
new file mode 100644
index 0000000..ae1a300
--- /dev/null
+++ b/src/screens/AttendeeDetails.js
@@ -0,0 +1,238 @@
+import React from "react";
+import {
+ Animated,
+ Platform,
+ StyleSheet,
+ TouchableOpacity,
+ Text,
+ ScrollView,
+ View,
+ Linking
+} from "react-native";
+import { Constants, WebBrowser } from "expo";
+import FadeIn from "react-native-fade-in-image";
+import { View as AnimatableView } from "react-native-animatable";
+import AnimatedScrollView from "../components/AnimatedScrollView";
+import NavigationBar from "../components/NavigationBar";
+import { Colors, FontSizes, Layout } from "../constants";
+import { RegularText, SemiBoldText } from "../components/StyledText";
+import GravatarImage from "../components/GravatarImage";
+import CloseButton from "../components/CloseButton";
+import Markdown from "react-native-simple-markdown";
+
+export default class Details extends React.Component {
+ state = {
+ scrollY: new Animated.Value(0)
+ };
+
+ render() {
+ let params = this.props.navigation.state.params || {};
+ const { answers, ...rest } = params.attendee;
+
+ const twitter = answers.find(item => item.question.id === 58);
+ const bio = answers.find(item => item.question.id === 56);
+ const job = answers.find(item => item.question.id === 59);
+
+ const attendee = {
+ ...rest,
+ twitter: twitter ? twitter.value : null,
+ bio: bio ? bio.value : null,
+ job: job ? job.value : null
+ };
+
+ const { scrollY } = this.state;
+ const scale = scrollY.interpolate({
+ inputRange: [-300, 0, 1],
+ outputRange: [2, 1, 1],
+ extrapolate: "clamp"
+ });
+ const translateX = 0;
+ const translateY = scrollY.interpolate({
+ inputRange: [-300, 0, 1],
+ outputRange: [-50, 1, 1],
+ extrapolate: "clamp"
+ });
+
+ const headerOpacity = scrollY.interpolate({
+ inputRange: [0, 30, 200],
+ outputRange: [0, 0, 1]
+ });
+
+ return (
+
+ {Platform.OS === "ios" ? (
+
+ ) : null}
+
+
+
+
+
+
+
+
+
+ {attendee.firstName + " " + attendee.lastName}
+
+
+
+
+ {attendee.bio && (
+
+ Bio
+ {attendee.bio}
+
+ )}
+ {attendee.job && (
+
+
+ Job Title
+
+ {attendee.job}
+
+ )}
+ {attendee.twitter && (
+
+
+ Twitter
+
+
+ this._handlePressSpeakerTwitter(attendee.twitter)
+ }
+ >
+
+ {attendee.twitter}
+
+
+
+ )}
+
+
+
+
+ (
+ 0 ? -5 : 0
+ }}
+ >
+ this.props.navigation.goBack()}
+ tintColor="#fff"
+ title={null}
+ />
+
+ )}
+ renderRightButton={() => null}
+ />
+
+ );
+ }
+
+ _renderTruncatedFooter = handlePress => {
+ return (
+
+
+ Read more
+
+
+ );
+ };
+
+ _handlePressSpeakerTwitter = async twitter => {
+ try {
+ await Linking.openURL(`twitter://user?screen_name=` + twitter);
+ } catch (e) {
+ WebBrowser.openBrowserAsync("https://twitter.com/" + twitter);
+ }
+ };
+}
+const markdownStyles = {
+ text: {}
+};
+const styles = StyleSheet.create({
+ container: {},
+ avatar: {
+ width: 100,
+ height: 100,
+ borderRadius: 50,
+ marginBottom: 10
+ },
+ content: {
+ backgroundColor: "#fff",
+ paddingBottom: 20,
+ paddingHorizontal: 20
+ },
+ headerContainer: {
+ backgroundColor: Colors.blue,
+ paddingTop: Constants.statusBarHeight + Layout.notchHeight + 20,
+ paddingBottom: 20,
+ paddingHorizontal: 20,
+ alignItems: "center",
+ justifyContent: "center"
+ },
+ headerText: {
+ color: "#fff",
+ fontSize: FontSizes.subtitle
+ },
+ twitterText: {
+ color: "#000",
+ fontSize: FontSizes.subtitle
+ },
+ sectionHeader: {
+ fontSize: FontSizes.bodyTitle,
+ marginTop: 15,
+ marginBottom: 3
+ }
+});
diff --git a/src/screens/Attendees.js b/src/screens/Attendees.js
new file mode 100644
index 0000000..c9c13c8
--- /dev/null
+++ b/src/screens/Attendees.js
@@ -0,0 +1,135 @@
+import React from "react";
+
+import {
+ Animated,
+ Linking,
+ Platform,
+ Text,
+ Image,
+ TouchableOpacity,
+ StyleSheet,
+ AsyncStorage,
+ View
+} from "react-native";
+import FadeIn from "react-native-fade-in-image";
+import { ScrollView } from "react-native-gesture-handler";
+import { WebBrowser } from "expo";
+
+import { Colors, FontSizes, Layout } from "../constants";
+import MenuButton from "../components/MenuButton";
+import { BoldText, SemiBoldText, RegularText } from "../components/StyledText";
+import LoadingPlaceholder from "../components/LoadingPlaceholder";
+import CachedImage from "../components/CachedImage";
+import SearchAttendees from "../components/SearchAttendees";
+import { RectButton } from "react-native-gesture-handler";
+
+export default class Attendees extends React.Component {
+ static navigationOptions = {
+ title: "Attendees",
+ headerStyle: { backgroundColor: Colors.blue },
+ headerTintColor: "white",
+ headerLeft: ,
+ headerTitleStyle: {
+ fontFamily: "open-sans-bold"
+ }
+ };
+
+ state = {
+ ready: Platform.OS === "android" ? false : true,
+ uuid: null
+ };
+
+ async getUUID() {
+ try {
+ const value = await AsyncStorage.getItem("@MySuperStore:tickets");
+ const tickets = JSON.parse(value);
+ const tix = tickets || [];
+ const uuid = tix.length > 0 && tickets[0].uuid;
+
+ this.setState({ uuid });
+ } catch (err) {
+ console.log(err);
+ return [];
+ }
+ }
+
+ constructor(props) {
+ super(props);
+ }
+
+ componentDidMount() {
+ this.getUUID();
+ if (this.state.ready) {
+ return;
+ }
+
+ setTimeout(() => {
+ this.setState({ ready: true });
+ }, 200);
+ }
+
+ render() {
+ if (!this.state.ready) {
+ return null;
+ }
+
+ const { uuid } = this.state;
+
+ if (uuid) {
+ return (
+ {
+ this._handlePressAttendee(attendee);
+ }}
+ />
+ );
+ } else {
+ return (
+
+
+
+ You need to scan your ticket first
+
+
+
+ );
+ }
+ }
+
+ _handlePressProfileQRButton = () => {
+ this.props.navigation.navigate({
+ routeName: "QRScanner",
+ key: "QRScanner"
+ });
+ };
+
+ _handlePressAttendee = attendee => {
+ this.props.navigation.navigate("AttendeeDetails", { attendee });
+ };
+}
+
+const BORDER_RADIUS = 3;
+
+const styles = StyleSheet.create({
+ bigButton: {
+ backgroundColor: Colors.blue,
+ paddingHorizontal: 15,
+ height: 50,
+ marginHorizontal: 15,
+ alignItems: "center",
+ justifyContent: "center",
+ borderRadius: BORDER_RADIUS,
+ overflow: "hidden",
+ flexDirection: "row"
+ },
+ bigButtonText: {
+ fontSize: FontSizes.normalButton,
+ color: "#fff",
+ textAlign: "center"
+ }
+});
diff --git a/src/screens/Contacts.js b/src/screens/Contacts.js
index 1b83ab4..e8ae19b 100644
--- a/src/screens/Contacts.js
+++ b/src/screens/Contacts.js
@@ -1,29 +1,29 @@
-import React from 'react';
+import React from "react";
import {
Animated,
Linking,
Platform,
StyleSheet,
AsyncStorage,
- View,
-} from 'react-native';
-import { WebBrowser } from 'expo';
-import { RectButton } from 'react-native-gesture-handler';
-import { View as AnimatableView } from 'react-native-animatable';
-import { withNavigation } from 'react-navigation';
-
-import AnimatedScrollView from '../components/AnimatedScrollView';
-import MyContacts from '../components/MyContacts';
-import NavigationBar from '../components/NavigationBar';
-import MenuButton from '../components/MenuButton';
-import { SemiBoldText } from '../components/StyledText';
-import { Colors, FontSizes, Layout } from '../constants';
-export const Schedule = require('../data/schedule.json');
+ View
+} from "react-native";
+import { WebBrowser } from "expo";
+import { RectButton } from "react-native-gesture-handler";
+import { View as AnimatableView } from "react-native-animatable";
+import { withNavigation } from "react-navigation";
+
+import AnimatedScrollView from "../components/AnimatedScrollView";
+import MyContacts from "../components/MyContacts";
+import NavigationBar from "../components/NavigationBar";
+import MenuButton from "../components/MenuButton";
+import { SemiBoldText } from "../components/StyledText";
+import { Colors, FontSizes, Layout } from "../constants";
+export const Schedule = require("../data/schedule.json");
const Event = Schedule.events[0];
class Contacts extends React.Component {
state = {
- scrollY: new Animated.Value(0),
+ scrollY: new Animated.Value(0)
};
render() {
@@ -31,7 +31,7 @@ class Contacts extends React.Component {
const headerOpacity = scrollY.interpolate({
inputRange: [0, 150],
outputRange: [0, 1],
- extrapolate: 'clamp',
+ extrapolate: "clamp"
});
return (
@@ -43,18 +43,19 @@ class Contacts extends React.Component {
onScroll={Animated.event(
[
{
- nativeEvent: { contentOffset: { y: scrollY } },
- },
+ nativeEvent: { contentOffset: { y: scrollY } }
+ }
],
{ useNativeDriver: true }
- )}>
+ )}
+ >
@@ -74,14 +75,13 @@ class Contacts extends React.Component {
@withNavigation
class DeferredContactsContent extends React.Component {
state = {
- ready: Platform.OS === 'android' ? false : true,
- tickets: [],
+ ready: Platform.OS === "android" ? false : true,
+ tickets: []
};
async getTickets() {
try {
- const value = await AsyncStorage.getItem('@MySuperStore:tickets');
- console.log('tickets', value);
+ const value = await AsyncStorage.getItem("@MySuperStore:tickets");
this.setState({ tickets: JSON.parse(value) });
this.tickets = JSON.parse(value);
} catch (err) {
@@ -110,8 +110,11 @@ class DeferredContactsContent extends React.Component {
if (!this.state.ready) {
return null;
}
- console.log('state', this.state);
- const tix = this.state.tickets || [];
+
+ const { tickets } = this.state;
+ const tix = tickets || [];
+ const uuid = tix.length > 0 && tickets[0].uuid;
+
return (
+ underlayColor="#fff"
+ >
{"Scan a contact badge's QR code"}
+ {
+ this._handlePressAttendee(attendee);
+ }}
+ />
) : (
+ underlayColor="#fff"
+ >
You need to scan your ticket first
@@ -147,25 +158,29 @@ class DeferredContactsContent extends React.Component {
_handlePressQRButton = () => {
this.props.navigation.navigate({
- routeName: 'QRContactScanner',
- key: 'QRContactScanner',
+ routeName: "QRContactScanner",
+ key: "QRContactScanner"
});
};
_handlePressProfileQRButton = () => {
this.props.navigation.navigate({
- routeName: 'QRScanner',
- key: 'QRScanner',
+ routeName: "QRScanner",
+ key: "QRScanner"
});
};
+ _handlePressAttendee = attendee => {
+ this.props.navigation.navigate("AttendeeDetails", { attendee });
+ };
+
_handlePressTwitterButton = async () => {
try {
await Linking.openURL(
`twitter://user?screen_name=` + Event.twitterHandle
);
} catch (e) {
- WebBrowser.openBrowserAsync('https://twitter.com/' + Event.twitterHandle);
+ WebBrowser.openBrowserAsync("https://twitter.com/" + Event.twitterHandle);
}
};
}
@@ -173,12 +188,12 @@ class DeferredContactsContent extends React.Component {
const OverscrollView = () => (
);
@@ -187,9 +202,10 @@ const ClipBorderRadius = ({ children, style }) => {
return (
+ { borderRadius: BORDER_RADIUS, overflow: "hidden", marginTop: 10 },
+ style
+ ]}
+ >
{children}
);
@@ -199,50 +215,50 @@ const BORDER_RADIUS = 3;
const styles = StyleSheet.create({
headerContent: {
- alignItems: 'center',
+ alignItems: "center",
marginTop: 5,
- paddingVertical: 10,
+ paddingVertical: 10
},
headerVideoLayer: {
- ...StyleSheet.absoluteFillObject,
+ ...StyleSheet.absoluteFillObject
},
headerVideoOverlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: Colors.blue,
- opacity: 0.8,
+ opacity: 0.8
},
headerText: {
- color: '#fff',
- textAlign: 'center',
+ color: "#fff",
+ textAlign: "center",
fontSize: 17,
- lineHeight: 17 * 1.5,
+ lineHeight: 17 * 1.5
},
headerSmallText: {
- color: '#fff',
- textAlign: 'center',
+ color: "#fff",
+ textAlign: "center",
fontSize: 7,
- lineHeight: 7 * 1.5,
+ lineHeight: 7 * 1.5
},
bigButton: {
backgroundColor: Colors.blue,
paddingHorizontal: 15,
height: 50,
marginHorizontal: 15,
- alignItems: 'center',
- justifyContent: 'center',
+ alignItems: "center",
+ justifyContent: "center",
borderRadius: BORDER_RADIUS,
- overflow: 'hidden',
- flexDirection: 'row',
+ overflow: "hidden",
+ flexDirection: "row"
},
bigButtonText: {
fontSize: FontSizes.normalButton,
- color: '#fff',
- textAlign: 'center',
+ color: "#fff",
+ textAlign: "center"
},
seeAllTalks: {
fontSize: FontSizes.normalButton,
- color: Colors.blue,
- },
+ color: Colors.blue
+ }
});
export default Contacts;
diff --git a/src/screens/index.js b/src/screens/index.js
index bebbeac..a5dd06f 100644
--- a/src/screens/index.js
+++ b/src/screens/index.js
@@ -1,8 +1,10 @@
import Crew from "./Crew";
import Details from "./Details";
+import AttendeeDetails from "./AttendeeDetails";
import Home from "./Home";
import ScheduleDay from "./ScheduleDay";
import Speakers from "./Speakers";
+import Attendees from "./Attendees";
import Sponsors from "./Sponsors";
import Profile from "./Profile";
import Contacts from "./Contacts";
@@ -12,6 +14,8 @@ import CheckedInAttendeeInfo from "./CheckedInAttendeeInfo";
export default {
Home,
Crew,
+ Attendees,
+ AttendeeDetails,
Details,
ScheduleDay,
Speakers,
diff --git a/yarn.lock b/yarn.lock
index 4baab00..4451243 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -511,6 +511,18 @@
lodash "^4.17.4"
react-native-vector-icons "4.5.0"
+"@types/async@2.0.49":
+ version "2.0.49"
+ resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0"
+
+"@types/graphql@0.12.6":
+ version "0.12.6"
+ resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.12.6.tgz#3d619198585fcabe5f4e1adfb5cf5f3388c66c13"
+
+"@types/zen-observable@^0.5.3":
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.3.tgz#91b728599544efbb7386d8b6633693a3c2e7ade5"
+
abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -642,6 +654,90 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
+apollo-boost@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.6.tgz#922d423536e408abfff816904ad2753d50feb9bf"
+ dependencies:
+ apollo-cache-inmemory "^1.2.1"
+ apollo-client "^2.3.1"
+ apollo-link "^1.0.6"
+ apollo-link-error "^1.0.3"
+ apollo-link-http "^1.3.1"
+ apollo-link-state "^0.4.0"
+ graphql-tag "^2.4.2"
+
+apollo-cache-inmemory@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.1.tgz#1f8222270aa7983eb9d2ac30057196378ab3bb01"
+ dependencies:
+ apollo-cache "^1.1.8"
+ apollo-utilities "^1.0.12"
+ graphql-anywhere "^4.1.10"
+
+apollo-cache@^1.1.8:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.8.tgz#b078d33dec876d52b5a81a325d3c254d4e362d3c"
+ dependencies:
+ apollo-utilities "^1.0.12"
+
+apollo-client@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.3.1.tgz#64b204779b7e8b21f901529527a9a9c973eb7fd4"
+ dependencies:
+ "@types/zen-observable" "^0.5.3"
+ apollo-cache "^1.1.8"
+ apollo-link "^1.0.0"
+ apollo-link-dedup "^1.0.0"
+ apollo-utilities "^1.0.12"
+ symbol-observable "^1.0.2"
+ zen-observable "^0.8.0"
+ optionalDependencies:
+ "@types/async" "2.0.49"
+
+apollo-link-dedup@^1.0.0:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.9.tgz#3c4e4af88ef027cbddfdb857c043fd0574051dad"
+ dependencies:
+ apollo-link "^1.2.2"
+
+apollo-link-error@^1.0.3:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.0.9.tgz#83bbe019a3bca7c602c399889b313a7e5e22713f"
+ dependencies:
+ apollo-link "^1.2.2"
+
+apollo-link-http-common@^0.2.4:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.4.tgz#877603f7904dc8f70242cac61808b1f8d034b2c3"
+ dependencies:
+ apollo-link "^1.2.2"
+
+apollo-link-http@^1.3.1:
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.4.tgz#b80b7b4b342c655b6a5614624b076a36be368f43"
+ dependencies:
+ apollo-link "^1.2.2"
+ apollo-link-http-common "^0.2.4"
+
+apollo-link-state@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.1.tgz#65e9e0e12c67936b8c4b12b8438434f393104579"
+ dependencies:
+ apollo-utilities "^1.0.8"
+ graphql-anywhere "^4.1.0-alpha.0"
+
+apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.2.tgz#54c84199b18ac1af8d63553a68ca389c05217a03"
+ dependencies:
+ "@types/graphql" "0.12.6"
+ apollo-utilities "^1.0.0"
+ zen-observable-ts "^0.8.9"
+
+apollo-utilities@^1.0.0, apollo-utilities@^1.0.12, apollo-utilities@^1.0.8:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.12.tgz#9e2b2a34cf89f3bf0d73a664effd8c1bb5d1b7f7"
+
append-transform@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
@@ -2936,7 +3032,17 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6,
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
-graphql@^0.13.1:
+graphql-anywhere@^4.1.0-alpha.0, graphql-anywhere@^4.1.10:
+ version "4.1.10"
+ resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.10.tgz#247ada0c8d85b9d5d6b37180973442ac68ff15de"
+ dependencies:
+ apollo-utilities "^1.0.12"
+
+graphql-tag@^2.4.2, graphql-tag@^2.9.2:
+ version "2.9.2"
+ resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.9.2.tgz#2f60a5a981375f430bf1e6e95992427dc18af686"
+
+graphql@^0.13.1, graphql@^0.13.2:
version "0.13.2"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270"
dependencies:
@@ -4056,6 +4162,10 @@ lodash.zipobject@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8"
+lodash@4.17.5:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
+
lodash@^3.5.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
@@ -5060,6 +5170,16 @@ rc@^1.0.1, rc@^1.1.2, rc@^1.1.6, rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
+react-apollo@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-2.1.4.tgz#a51059ac56f1a7997cad636a5d36398b9c93ff12"
+ dependencies:
+ fbjs "^0.8.16"
+ hoist-non-react-statics "^2.5.0"
+ invariant "^2.2.2"
+ lodash "4.17.5"
+ prop-types "^15.6.0"
+
react-clone-referenced-element@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.0.1.tgz#2bba8c69404c5e4a944398600bcc4c941f860682"
@@ -6069,6 +6189,10 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
+symbol-observable@^1.0.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
+
symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
@@ -6692,3 +6816,13 @@ yauzl@2.4.1:
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"
dependencies:
fd-slicer "~1.0.1"
+
+zen-observable-ts@^0.8.9:
+ version "0.8.9"
+ resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.9.tgz#d3c97af08c0afdca37ebcadf7cc3ee96bda9bab1"
+ dependencies:
+ zen-observable "^0.8.0"
+
+zen-observable@^0.8.0:
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.8.tgz#1ea93995bf098754a58215a1e0a7309e5749ec42"