Commit e542732b authored by Nikolai R Kristiansen's avatar Nikolai R Kristiansen

馃帹 Fix linter errors and refactor abit

parent 148ea8e7
Pipeline #707 failed with stage
in 1 minute and 47 seconds
......@@ -12,6 +12,8 @@
"no-underscore-dangle": 0,
"no-param-reassign": 0,
"react/prefer-stateless-function": 1,
"react/prop-types": 1, // FIXME: refactor
"class-methods-use-this": 1, // FIXME: refactor
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"react/sort-comp": 0,
"max-len": 0,
......
import React, { Component } from 'react';
import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/es/integration/react';
import Config from 'react-native-config';
......@@ -15,16 +15,14 @@ const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
});
export default class App extends Component {
render() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<ApolloProvider client={apolloClient}>
<Dusken />
</ApolloProvider>
</PersistGate>
</Provider>
);
}
export default function App() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<ApolloProvider client={apolloClient}>
<Dusken />
</ApolloProvider>
</PersistGate>
</Provider>
);
}
import React, { Component } from 'react';
import React from 'react';
import { connect } from 'react-redux';
import { Root } from 'native-base';
import DuskenNavigation from './navigation';
class DuskenContainer extends Component {
render() {
return (
<Root>
<DuskenNavigation />
</Root>
);
}
}
const DuskenContainer = () => (
<Root>
<DuskenNavigation />
</Root>
);
export default connect()(DuskenContainer);
......@@ -51,7 +51,7 @@ export function requestLogin(username, password) {
};
}
export function requestUserData(auth_token) {
export function requestUserData(authToken) {
return (dispatch) => {
// We are now fetching user data
dispatch(userDataRequest());
......@@ -61,7 +61,7 @@ export function requestUserData(auth_token) {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Token ${auth_token}`,
Authorization: `Token ${authToken}`,
},
})
.then((response) => response.json().then((json) => ({ json, response })))
......@@ -118,7 +118,7 @@ export function requestRegisterUser(firstName, lastName, email, phoneNumber, pas
};
}
export function requestMembershipCharge(auth_token, stripe_token, membership_type) {
export function requestMembershipCharge(authToken, stripeToken, membershipType) {
return (dispatch) => {
dispatch(membershipChargeRequest());
......@@ -127,11 +127,11 @@ export function requestMembershipCharge(auth_token, stripe_token, membership_typ
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Token ${auth_token}`,
Authorization: `Token ${authToken}`,
},
body: JSON.stringify({
stripe_token,
membership_type,
stripe_token: stripeToken,
membership_type: membershipType,
payment_method: 'app',
}),
})
......
import React, { Component } from 'react';
import { Text, ScrollView, View, Platform, StyleSheet, Image, Linking, TouchableOpacity } from 'react-native';
// import HTMLView from 'react-native-htmlview';
import { Text, View, Platform, StyleSheet, Image, Linking, TouchableOpacity } from 'react-native';
import { ScrollView } from 'react-navigation';
import { Button, Text as NBText, Icon } from 'native-base';
import theme from '../../theme';
......@@ -140,8 +140,6 @@ export default class About extends Component {
Alle studentforeninger i Oslo kan arrangere gratis p Chateau Neuf. Skal du arrangere en fest, sette en
konsert, holde et foredrag eller gjennomfre et mte, har vi lokaler som kan brukes til dette.
</Text>
{/* <HTMLView style={styles.content} stylesheet={HTMLStyles} value={this.props.openingHours}/> */}
</View>
</ScrollView>
);
......
import { connect } from 'react-redux';
import React, { Component } from 'react';
import React from 'react';
import About from './About';
class AboutContainer extends Component {
render() {
return <About {...this.state} />;
}
}
const AboutContainer = () => <About />;
export default connect()(AboutContainer);
export default AboutContainer;
......@@ -3,6 +3,7 @@ import { Linking, StyleSheet, ScrollView, Text, Platform, View, Image, Touchable
import HTMLView from 'react-native-htmlview';
import moment from 'moment';
import { Icon } from 'native-base';
import theme from '../../theme';
moment.locale('nb');
......@@ -44,8 +45,8 @@ export default class EventDetail extends Component {
_formatTicketText() {
/* FIXME: This should be handled by API */
const { item } = this.props;
let reg_kr = '';
let mem_kr = '';
let regularPrice = '';
let memberPrice = '';
if (item.price_regular === '0') {
item.price_regular = 'Gratis';
}
......@@ -53,19 +54,19 @@ export default class EventDetail extends Component {
item.price_member = 'Gratis';
}
if (item.price_regular !== 'Gratis') {
reg_kr = ' kr';
regularPrice = ' kr';
}
if (item.price_member !== 'Gratis') {
mem_kr = ' kr';
memberPrice = ' kr';
}
let text = '';
if (item.price_regular && item.price_member) {
text = `Pris: ${item.price_regular}${reg_kr} / Medlemmer: ${item.price_member}${mem_kr}`;
text = `Pris: ${item.price_regular}${regularPrice} / Medlemmer: ${item.price_member}${memberPrice}`;
} else if (item.price_regular) {
text = `Pris: ${item.price_regular}${reg_kr}`;
text = `Pris: ${item.price_regular}${regularPrice}`;
} else if (item.price_member) {
text = `Pris (Medlemmer): ${item.price_member}${mem_kr}`;
text = `Pris (Medlemmer): ${item.price_member}${memberPrice}`;
} else {
return '';
}
......@@ -108,7 +109,7 @@ export default class EventDetail extends Component {
const text = this._formatTicketText();
if (text === '') {
return;
return null;
}
if (item.ticket_url) {
......@@ -141,7 +142,7 @@ export default class EventDetail extends Component {
showFacebutton() {
const { item } = this.props;
if (!item.facebook_url) {
return;
return null;
}
return (
......@@ -162,6 +163,8 @@ export default class EventDetail extends Component {
if (item.thumbnail.medium_large) {
return <Image source={{ uri: item.thumbnail.medium_large }} style={styles.image} />;
}
return null;
}
showYear() {
......@@ -170,6 +173,8 @@ export default class EventDetail extends Component {
if (moment().year() !== moment(item.start_time).year()) {
return <Text style={styles.year}>{this._formatYear(item.start_time)}</Text>;
}
return null;
}
render() {
......
import { StyleSheet, View, Platform } from 'react-native';
import { SectionList } from 'react-navigation';
import { Card, ListItem, CardItem, Body, Text, Left, Right, Icon, Button, Content, Spinner } from 'native-base';
import { Card, ListItem, CardItem, Body, Text, Right, Icon, Button, Content, Spinner } from 'native-base';
import React, { Component } from 'react';
import moment from 'moment';
import 'moment/locale/nb';
......@@ -64,11 +64,7 @@ export default class EventList extends Component {
return (
<Content>
<Card style={{ margin: 4 }}>
<CardItem
onPress={() => {
this._onPressItem(item);
}}
>
<CardItem>
<Text style={styles.loadingText}>Kunne ikke hente programmet...</Text>
</CardItem>
<CardItem>
......
......@@ -6,6 +6,7 @@ import moment from 'moment';
import 'moment/locale/nb';
import EventList from './EventList';
import { fetchWithTimeout } from '../../utils';
moment.locale('nb');
......@@ -35,7 +36,7 @@ class EventListContainer extends Component {
_toSectionFormat(events) {
const sectioned = {};
events.map((event) => {
events.forEach((event) => {
const title = this._formatDate(event.start_time);
if (title in sectioned) {
sectioned[title].push(event);
......@@ -84,9 +85,9 @@ class EventListContainer extends Component {
const url = `${Config.EVENT_API_URL}/wp-json/wp/v2/events?page=${page}&future=1`;
this.setState({ loading: true });
fetch(url)
fetchWithTimeout(url)
.then((res) => {
this.setState({ totalPages: parseInt(res.headers.get('x-wp-totalpages')) });
this.setState({ totalPages: parseInt(res.headers.get('x-wp-totalpages'), 10) });
return res.json();
})
.then((res) => {
......
import React, { Component } from 'react';
import { Linking, StyleSheet, View, Platform } from 'react-native';
import { Container, Header, Content, Form, Item, Input, Label, Spinner, Button, Text, Icon } from 'native-base';
import { Linking, StyleSheet, View } from 'react-native';
import { Container, Content, Form, Item, Input, Label, Spinner, Button, Text } from 'native-base';
import Config from 'react-native-config';
import theme from '../../theme';
......@@ -26,7 +26,7 @@ export default class Login extends Component {
returnKeyType="next"
onChangeText={this.handleEmail}
onSubmitEditing={() => {
this.refs.passwordInput._root.focus();
this.passwordInputRef._root.focus();
}}
/>
</Item>
......@@ -44,7 +44,7 @@ export default class Login extends Component {
returnKeyType="next"
onChangeText={this.handleEmail}
onSubmitEditing={() => {
this.refs.passwordInput._root.focus();
this.passwordInputRef._root.focus();
}}
/>
</Item>
......@@ -57,7 +57,9 @@ export default class Login extends Component {
<Item stackedLabel last error>
<Label>Passord</Label>
<Input
ref="passwordInput"
ref={(ref) => {
this.passwordInputRef = ref;
}}
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
......@@ -71,7 +73,9 @@ export default class Login extends Component {
<Item stackedLabel last>
<Label>Passord</Label>
<Input
ref="passwordInput"
ref={(ref) => {
this.passwordInputRef = ref;
}}
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
......@@ -125,11 +129,7 @@ export default class Login extends Component {
return <View style={styles.errorBox} />;
};
showSpinner = () => {
if (this.props.isLoggingIn) {
return <Spinner color="#f58220" />;
}
};
showSpinner = () => (this.props.isLoggingIn ? <Spinner color="#f58220" /> : null);
handleEmail = (text) => {
this.setState({ email: text });
......
......@@ -44,7 +44,7 @@ export default class Proof extends Component {
membershipValidTo() {
if (!this.props.user.last_membership) {
return;
return null;
}
let validTo = this.props.user.last_membership.end_date;
......@@ -63,7 +63,7 @@ export default class Proof extends Component {
membershipStatus() {
if (!this.props.user.is_member) {
if (!this.props.user.last_membership) {
return;
return null;
}
return (
......@@ -86,7 +86,7 @@ export default class Proof extends Component {
purchaseButton() {
if (this.props.user.is_member) {
return;
return null;
}
return (
......@@ -108,15 +108,24 @@ export default class Proof extends Component {
}
confetti() {
if (this.props.user.is_member) {
// Confetti!!!!
return <Confetti ref={(node) => (this._confettiView = node)} confettiCount={Number.MAX_SAFE_INTEGER} />;
if (!this.props.user.is_member) {
return null;
}
// Confetti!!!!
return (
<Confetti
ref={(node) => {
this._confettiView = node;
}}
confettiCount={Number.MAX_SAFE_INTEGER}
/>
);
}
logo() {
if (!this.props.user.is_member) {
return;
return null;
}
// FIXME: URL to config
......@@ -133,7 +142,7 @@ export default class Proof extends Component {
chargeError() {
if (!this.props.chargeError) {
return;
return null;
}
return (
......
......@@ -62,7 +62,7 @@ class ProofContainer extends Component {
membershipTypeSlug
);
},
(error) => {
() => {
/* FIXME: Happens only if card dialog is canceled? */
}
);
......
import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label, Spinner, Button, Text, Icon, Toast } from 'native-base';
import { Container, Content, Form, Item, Input, Label, Spinner, Button, Text, Icon, Toast } from 'native-base';
import { StyleSheet, View } from 'react-native';
import EmailValidator from 'email-validator';
import * as EmailValidator from 'email-validator';
import theme from '../../theme';
......@@ -27,7 +27,7 @@ export default class UserRegister extends Component {
const touched = new Set(this.state.touched).add(triggeredBy);
/* No empty fields */
for (const key of fieldNames) {
fieldNames.forEach((key) => {
const value = this.state[key];
if (value === '') {
errors[key] = 'kan ikke v忙re tomt';
......@@ -36,7 +36,7 @@ export default class UserRegister extends Component {
} else {
delete errors[key];
}
}
});
this.setState({ errors, touched });
}
......@@ -62,7 +62,7 @@ export default class UserRegister extends Component {
});
}}
onSubmitEditing={() => {
this.refs.lastNameInput._root.focus();
this.lastNameInputRef._root.focus();
}}
value={this.state.firstName}
/>
......@@ -76,7 +76,9 @@ export default class UserRegister extends Component {
<Item error={this.fieldHasError('lastName')}>
<Label>Etternavn</Label>
<Input
ref="lastNameInput"
ref={(ref) => {
this.lastNameInputRef = ref;
}}
returnKeyType="next"
onChangeText={(lastName) => {
this.setState({ lastName }, () => {
......@@ -84,7 +86,7 @@ export default class UserRegister extends Component {
});
}}
onSubmitEditing={() => {
this.refs.emailInput._root.focus();
this.emailInputRef._root.focus();
}}
value={this.state.lastName}
/>
......@@ -98,7 +100,9 @@ export default class UserRegister extends Component {
<Item error={this.fieldHasError('email')}>
<Label>E-post</Label>
<Input
ref="emailInput"
ref={(ref) => {
this.emailInputRef = ref;
}}
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
......@@ -109,7 +113,7 @@ export default class UserRegister extends Component {
});
}}
onSubmitEditing={() => {
this.refs.phoneInput._root.focus();
this.phoneInputRef._root.focus();
}}
value={this.state.email}
/>
......@@ -123,7 +127,9 @@ export default class UserRegister extends Component {
<Item error={this.fieldHasError('phoneNumber')}>
<Label>Mobilnummer</Label>
<Input
ref="phoneInput"
ref={(ref) => {
this.phoneInputRef = ref;
}}
returnKeyType="next"
keyboardType="phone-pad"
onChangeText={(phoneNumber) => {
......@@ -132,7 +138,7 @@ export default class UserRegister extends Component {
});
}}
onSubmitEditing={() => {
this.refs.passwordInput._root.focus();
this.passwordInputRef._root.focus();
}}
value={this.state.phoneNumber}
/>
......@@ -146,7 +152,9 @@ export default class UserRegister extends Component {
<Item error={this.fieldHasError('password')}>
<Label>Passord</Label>
<Input
ref="passwordInput"
ref={(ref) => {
this.passwordInputRef = ref;
}}
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
......@@ -195,7 +203,7 @@ export default class UserRegister extends Component {
showFieldError = (field) => {
if (!this.fieldHasError(field)) {
return;
return null;
}
return (
<Item style={styles.errorText}>
......@@ -205,9 +213,10 @@ export default class UserRegister extends Component {
};
showSpinner = () => {
if (this.props.isRegisteringUser) {
return <Spinner color="#f58220" />;
if (!this.props.isRegisteringUser) {
return null;
}
return <Spinner color="#f58220" />;
};
render() {
......
......@@ -62,11 +62,24 @@ const tabBarOptions = {
const tabNav = createBottomTabNavigator(tabBarRoutes, tabBarOptions);
const DuskenNavigation = createStackNavigator({
Root: tabNav,
Login: LoginScreen,
UserRegister: UserRegisterScreen,
EventDetail: EventDetailScreen,
});
const DuskenNavigation = createStackNavigator(
{
Root: tabNav,
Login: LoginScreen,
UserRegister: UserRegisterScreen,
EventDetail: EventDetailScreen,
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
},
}
);
export default createAppContainer(DuskenNavigation);
......@@ -33,9 +33,9 @@ const initialState = {
function formatErrors(errs) {
const _errs = {};
for (const [key, value] of Object.entries(errs)) {
Object.entries(errs).forEach(([key, value]) => {
_errs[snakeToCamelCase(key)] = Array.isArray(value) ? value.join('\n') : value;
}
});
return _errs;
}
......@@ -97,7 +97,9 @@ export default function duskenApp(state = initialState, action) {
});
case REGISTER_USER_SUCCESS:
// eslint-disable-next-line no-case-declarations
const userData = action.data;
// eslint-disable-next-line no-case-declarations
const token = action.data.auth_token;
delete userData.auth_token;
......
import React, { Component } from 'react';
import React from 'react';
import Icon from 'react-native-vector-icons/SimpleLineIcons';
import { StyleProvider } from 'native-base';
import AboutContainer from '../modules/about/AboutContainer';
import getTheme from '../../native-base-theme/components';
export default class AboutScreen extends Component {
static navigationOptions = {
title: 'Om oss',
tabBarIcon: ({ tintColor }) => <Icon name="info" size={16} color={tintColor} style={{ marginTop: 5 }} />,
};
const AboutScreen = () => (
<StyleProvider style={getTheme()}>
<AboutContainer />
</StyleProvider>
);
render() {
return (
<StyleProvider style={getTheme()}>
<AboutContainer />
</StyleProvider>
);
}
}
const TabBarIcon = ({ tintColor }) => <Icon name="info" size={16} color={tintColor} style={{ marginTop: 5 }} />;
AboutScreen.navigationOptions = {
title: 'Om oss',
tabBarIcon: TabBarIcon,
};
export default AboutScreen;
import React, { Component } from 'react';
import React from 'react';
import { StyleProvider } from 'native-base';
import { useNavigationParam } from 'react-navigation-hooks/src/Hooks';
import EventDetail from '../modules/events/EventDetail';
import getTheme from '../../native-base-theme/components';
export default class EventDetailScreen extends Component {
static navigationOptions = ({ navigation }) => ({
title: navigation.state.params.item.title.decoded,
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
});
const EventDetailScreen = () => {
const item = useNavigationParam('item');
return (
<StyleProvider style={getTheme()}>
<EventDetail item={item} />
</StyleProvider>
);
};
EventDetailScreen.navigationOptions = ({ navigation }) => ({
title: navigation.state.params.item.title.decoded,
});
render() {
const { params } = this.props.navigation.state;
return (
<StyleProvider style={getTheme()}>
<EventDetail item={params.item} />
</StyleProvider>
);
}
}
export default EventDetailScreen;
import React, { Component } from 'react';