forked from vergnet/application-amicale
Improve Services components to match linter
This commit is contained in:
parent
6b12b4cde2
commit
33d98b024b
9 changed files with 718 additions and 682 deletions
|
@ -1,72 +1,73 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Animated, Dimensions} from "react-native";
|
import {Animated, Dimensions} from 'react-native';
|
||||||
import ImageListItem from "./ImageListItem";
|
import type {ViewStyle} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||||
import CardListItem from "./CardListItem";
|
import ImageListItem from './ImageListItem';
|
||||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
import CardListItem from './CardListItem';
|
||||||
|
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
dataset: Array<cardItem>,
|
dataset: Array<ServiceItemType>,
|
||||||
isHorizontal: boolean,
|
isHorizontal?: boolean,
|
||||||
contentContainerStyle?: ViewStyle,
|
contentContainerStyle?: ViewStyle | null,
|
||||||
}
|
|
||||||
|
|
||||||
export type cardItem = {
|
|
||||||
key: string,
|
|
||||||
title: string,
|
|
||||||
subtitle: string,
|
|
||||||
image: string | number,
|
|
||||||
onPress: () => void,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type cardList = Array<cardItem>;
|
export default class CardList extends React.Component<PropsType> {
|
||||||
|
static defaultProps = {
|
||||||
|
isHorizontal: false,
|
||||||
|
contentContainerStyle: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
windowWidth: number;
|
||||||
|
|
||||||
export default class CardList extends React.Component<Props> {
|
horizontalItemSize: number;
|
||||||
|
|
||||||
static defaultProps = {
|
constructor(props: PropsType) {
|
||||||
isHorizontal: false,
|
super(props);
|
||||||
|
this.windowWidth = Dimensions.get('window').width;
|
||||||
|
this.horizontalItemSize = this.windowWidth / 4; // So that we can fit 3 items and a part of the 4th => user knows he can scroll
|
||||||
|
}
|
||||||
|
|
||||||
|
getRenderItem = ({item}: {item: ServiceItemType}): React.Node => {
|
||||||
|
const {props} = this;
|
||||||
|
if (props.isHorizontal)
|
||||||
|
return (
|
||||||
|
<ImageListItem
|
||||||
|
item={item}
|
||||||
|
key={item.title}
|
||||||
|
width={this.horizontalItemSize}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
return <CardListItem item={item} key={item.title} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
keyExtractor = (item: ServiceItemType): string => item.key;
|
||||||
|
|
||||||
|
render(): React.Node {
|
||||||
|
const {props} = this;
|
||||||
|
let containerStyle = {};
|
||||||
|
if (props.isHorizontal) {
|
||||||
|
containerStyle = {
|
||||||
|
height: this.horizontalItemSize + 50,
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return (
|
||||||
windowWidth: number;
|
<Animated.FlatList
|
||||||
horizontalItemSize: number;
|
data={props.dataset}
|
||||||
|
renderItem={this.getRenderItem}
|
||||||
constructor(props: Props) {
|
keyExtractor={this.keyExtractor}
|
||||||
super(props);
|
numColumns={props.isHorizontal ? undefined : 2}
|
||||||
this.windowWidth = Dimensions.get('window').width;
|
horizontal={props.isHorizontal}
|
||||||
this.horizontalItemSize = this.windowWidth/4; // So that we can fit 3 items and a part of the 4th => user knows he can scroll
|
contentContainerStyle={
|
||||||
}
|
props.isHorizontal ? containerStyle : props.contentContainerStyle
|
||||||
|
|
||||||
renderItem = ({item}: { item: cardItem }) => {
|
|
||||||
if (this.props.isHorizontal)
|
|
||||||
return <ImageListItem item={item} key={item.title} width={this.horizontalItemSize}/>;
|
|
||||||
else
|
|
||||||
return <CardListItem item={item} key={item.title}/>;
|
|
||||||
};
|
|
||||||
|
|
||||||
keyExtractor = (item: cardItem) => item.key;
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let containerStyle = {};
|
|
||||||
if (this.props.isHorizontal) {
|
|
||||||
containerStyle = {
|
|
||||||
height: this.horizontalItemSize + 50,
|
|
||||||
justifyContent: 'space-around',
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return (
|
pagingEnabled={props.isHorizontal}
|
||||||
<Animated.FlatList
|
snapToInterval={
|
||||||
{...this.props}
|
props.isHorizontal ? (this.horizontalItemSize + 5) * 3 : null
|
||||||
data={this.props.dataset}
|
}
|
||||||
renderItem={this.renderItem}
|
/>
|
||||||
keyExtractor={this.keyExtractor}
|
);
|
||||||
numColumns={this.props.isHorizontal ? undefined : 2}
|
}
|
||||||
horizontal={this.props.isHorizontal}
|
|
||||||
contentContainerStyle={this.props.isHorizontal ? containerStyle : this.props.contentContainerStyle}
|
|
||||||
pagingEnabled={this.props.isHorizontal}
|
|
||||||
snapToInterval={this.props.isHorizontal ? (this.horizontalItemSize+5)*3 : null}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,50 +2,41 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Caption, Card, Paragraph, TouchableRipple} from 'react-native-paper';
|
import {Caption, Card, Paragraph, TouchableRipple} from 'react-native-paper';
|
||||||
import {View} from "react-native";
|
import {View} from 'react-native';
|
||||||
import type {cardItem} from "./CardList";
|
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
item: cardItem,
|
item: ServiceItemType,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class CardListItem extends React.Component<Props> {
|
export default class CardListItem extends React.Component<PropsType> {
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
shouldComponentUpdate() {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
render(): React.Node {
|
||||||
render() {
|
const {props} = this;
|
||||||
const props = this.props;
|
const {item} = props;
|
||||||
const item = props.item;
|
const source =
|
||||||
const source = typeof item.image === "number"
|
typeof item.image === 'number' ? item.image : {uri: item.image};
|
||||||
? item.image
|
return (
|
||||||
: {uri: item.image};
|
<Card
|
||||||
return (
|
style={{
|
||||||
<Card
|
width: '40%',
|
||||||
style={{
|
margin: 5,
|
||||||
width: '40%',
|
marginLeft: 'auto',
|
||||||
margin: 5,
|
marginRight: 'auto',
|
||||||
marginLeft: 'auto',
|
}}>
|
||||||
marginRight: 'auto',
|
<TouchableRipple style={{flex: 1}} onPress={item.onPress}>
|
||||||
}}
|
<View>
|
||||||
>
|
<Card.Cover style={{height: 80}} source={source} />
|
||||||
<TouchableRipple
|
<Card.Content>
|
||||||
style={{flex: 1}}
|
<Paragraph>{item.title}</Paragraph>
|
||||||
onPress={item.onPress}>
|
<Caption>{item.subtitle}</Caption>
|
||||||
<View>
|
</Card.Content>
|
||||||
<Card.Cover
|
</View>
|
||||||
style={{height: 80}}
|
</TouchableRipple>
|
||||||
source={source}
|
</Card>
|
||||||
/>
|
);
|
||||||
<Card.Content>
|
}
|
||||||
<Paragraph>{item.title}</Paragraph>
|
|
||||||
<Caption>{item.subtitle}</Caption>
|
|
||||||
</Card.Content>
|
|
||||||
</View>
|
|
||||||
</TouchableRipple>
|
|
||||||
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,53 +3,52 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Text, TouchableRipple} from 'react-native-paper';
|
import {Text, TouchableRipple} from 'react-native-paper';
|
||||||
import {Image, View} from 'react-native';
|
import {Image, View} from 'react-native';
|
||||||
import type {cardItem} from "./CardList";
|
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
item: cardItem,
|
item: ServiceItemType,
|
||||||
width: number,
|
width: number,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class ImageListItem extends React.Component<Props> {
|
export default class ImageListItem extends React.Component<PropsType> {
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
shouldComponentUpdate() {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
render(): React.Node {
|
||||||
render() {
|
const {props} = this;
|
||||||
const item = this.props.item;
|
const {item} = props;
|
||||||
const source = typeof item.image === "number"
|
const source =
|
||||||
? item.image
|
typeof item.image === 'number' ? item.image : {uri: item.image};
|
||||||
: {uri: item.image};
|
return (
|
||||||
return (
|
<TouchableRipple
|
||||||
<TouchableRipple
|
style={{
|
||||||
style={{
|
width: props.width,
|
||||||
width: this.props.width,
|
height: props.width + 40,
|
||||||
height: this.props.width + 40,
|
margin: 5,
|
||||||
margin: 5,
|
}}
|
||||||
}}
|
onPress={item.onPress}>
|
||||||
onPress={item.onPress}
|
<View>
|
||||||
>
|
<Image
|
||||||
<View>
|
style={{
|
||||||
<Image
|
width: props.width - 20,
|
||||||
style={{
|
height: props.width - 20,
|
||||||
width: this.props.width - 20,
|
marginLeft: 'auto',
|
||||||
height: this.props.width - 20,
|
marginRight: 'auto',
|
||||||
marginLeft: 'auto',
|
}}
|
||||||
marginRight: 'auto',
|
source={source}
|
||||||
}}
|
/>
|
||||||
source={source}
|
<Text
|
||||||
/>
|
style={{
|
||||||
<Text style={{
|
marginTop: 5,
|
||||||
marginTop: 5,
|
marginLeft: 'auto',
|
||||||
marginLeft: 'auto',
|
marginRight: 'auto',
|
||||||
marginRight: 'auto',
|
textAlign: 'center',
|
||||||
textAlign: 'center'
|
}}>
|
||||||
}}>
|
{item.title}
|
||||||
{item.title}
|
</Text>
|
||||||
</Text>
|
</View>
|
||||||
</View>
|
</TouchableRipple>
|
||||||
</TouchableRipple>
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import type {ServiceItem} from './ServicesManager';
|
import type {ServiceItemType} from './ServicesManager';
|
||||||
import ServicesManager from './ServicesManager';
|
import ServicesManager from './ServicesManager';
|
||||||
import {getSublistWithIds} from '../utils/Utils';
|
import {getSublistWithIds} from '../utils/Utils';
|
||||||
import AsyncStorageManager from './AsyncStorageManager';
|
import AsyncStorageManager from './AsyncStorageManager';
|
||||||
|
|
||||||
export default class DashboardManager extends ServicesManager {
|
export default class DashboardManager extends ServicesManager {
|
||||||
getCurrentDashboard(): Array<ServiceItem | null> {
|
getCurrentDashboard(): Array<ServiceItemType | null> {
|
||||||
const dashboardIdList = AsyncStorageManager.getObject(
|
const dashboardIdList = AsyncStorageManager.getObject(
|
||||||
AsyncStorageManager.PREFERENCES.dashboardItems.key,
|
AsyncStorageManager.PREFERENCES.dashboardItems.key,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,378 +1,384 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import i18n from "i18n-js";
|
import i18n from 'i18n-js';
|
||||||
import AvailableWebsites from "../constants/AvailableWebsites";
|
import {StackNavigationProp} from '@react-navigation/stack';
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import AvailableWebsites from '../constants/AvailableWebsites';
|
||||||
import ConnectionManager from "./ConnectionManager";
|
import ConnectionManager from './ConnectionManager';
|
||||||
import type {fullDashboard} from "../screens/Home/HomeScreen";
|
import type {FullDashboardType} from '../screens/Home/HomeScreen';
|
||||||
|
import getStrippedServicesList from '../utils/Services';
|
||||||
|
|
||||||
// AMICALE
|
// AMICALE
|
||||||
const CLUBS_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Clubs.png";
|
const CLUBS_IMAGE =
|
||||||
const PROFILE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProfilAmicaliste.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Clubs.png';
|
||||||
const EQUIPMENT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Materiel.png";
|
const PROFILE_IMAGE =
|
||||||
const VOTE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Vote.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/ProfilAmicaliste.png';
|
||||||
const AMICALE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/WebsiteAmicale.png";
|
const EQUIPMENT_IMAGE =
|
||||||
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Materiel.png';
|
||||||
|
const VOTE_IMAGE = 'https://etud.insa-toulouse.fr/~amicale_app/images/Vote.png';
|
||||||
|
const AMICALE_IMAGE =
|
||||||
|
'https://etud.insa-toulouse.fr/~amicale_app/images/WebsiteAmicale.png';
|
||||||
|
|
||||||
// STUDENTS
|
// STUDENTS
|
||||||
const PROXIMO_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png"
|
const PROXIMO_IMAGE =
|
||||||
const WIKETUD_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Wiketud.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
|
||||||
const EE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/EEC.png";
|
const WIKETUD_IMAGE =
|
||||||
const TUTORINSA_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/TutorINSA.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Wiketud.png';
|
||||||
|
const EE_IMAGE = 'https://etud.insa-toulouse.fr/~amicale_app/images/EEC.png';
|
||||||
|
const TUTORINSA_IMAGE =
|
||||||
|
'https://etud.insa-toulouse.fr/~amicale_app/images/TutorINSA.png';
|
||||||
|
|
||||||
// INSA
|
// INSA
|
||||||
const BIB_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Bib.png";
|
const BIB_IMAGE = 'https://etud.insa-toulouse.fr/~amicale_app/images/Bib.png';
|
||||||
const RU_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/RU.png";
|
const RU_IMAGE = 'https://etud.insa-toulouse.fr/~amicale_app/images/RU.png';
|
||||||
const ROOM_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Salles.png";
|
const ROOM_IMAGE =
|
||||||
const EMAIL_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Bluemind.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Salles.png';
|
||||||
const ENT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ENT.png";
|
const EMAIL_IMAGE =
|
||||||
const ACCOUNT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Account.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Bluemind.png';
|
||||||
|
const ENT_IMAGE = 'https://etud.insa-toulouse.fr/~amicale_app/images/ENT.png';
|
||||||
|
const ACCOUNT_IMAGE =
|
||||||
|
'https://etud.insa-toulouse.fr/~amicale_app/images/Account.png';
|
||||||
|
|
||||||
// SPECIAL
|
// SPECIAL
|
||||||
const WASHER_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashLaveLinge.png";
|
const WASHER_IMAGE =
|
||||||
const DRYER_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashSecheLinge.png";
|
'https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashLaveLinge.png';
|
||||||
|
const DRYER_IMAGE =
|
||||||
|
'https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashSecheLinge.png';
|
||||||
|
|
||||||
const AMICALE_LOGO = require("../../assets/amicale.png");
|
const AMICALE_LOGO = require('../../assets/amicale.png');
|
||||||
|
|
||||||
export const SERVICES_KEY = {
|
export const SERVICES_KEY = {
|
||||||
CLUBS: "clubs",
|
CLUBS: 'clubs',
|
||||||
PROFILE: "profile",
|
PROFILE: 'profile',
|
||||||
EQUIPMENT: "equipment",
|
EQUIPMENT: 'equipment',
|
||||||
AMICALE_WEBSITE: "amicale_website",
|
AMICALE_WEBSITE: 'amicale_website',
|
||||||
VOTE: "vote",
|
VOTE: 'vote',
|
||||||
PROXIMO: "proximo",
|
PROXIMO: 'proximo',
|
||||||
WIKETUD: "wiketud",
|
WIKETUD: 'wiketud',
|
||||||
ELUS_ETUDIANTS: "elus_etudiants",
|
ELUS_ETUDIANTS: 'elus_etudiants',
|
||||||
TUTOR_INSA: "tutor_insa",
|
TUTOR_INSA: 'tutor_insa',
|
||||||
RU: "ru",
|
RU: 'ru',
|
||||||
AVAILABLE_ROOMS: "available_rooms",
|
AVAILABLE_ROOMS: 'available_rooms',
|
||||||
BIB: "bib",
|
BIB: 'bib',
|
||||||
EMAIL: "email",
|
EMAIL: 'email',
|
||||||
ENT: "ent",
|
ENT: 'ent',
|
||||||
INSA_ACCOUNT: "insa_account",
|
INSA_ACCOUNT: 'insa_account',
|
||||||
WASHERS: "washers",
|
WASHERS: 'washers',
|
||||||
DRYERS: "dryers",
|
DRYERS: 'dryers',
|
||||||
}
|
};
|
||||||
|
|
||||||
export const SERVICES_CATEGORIES_KEY = {
|
export const SERVICES_CATEGORIES_KEY = {
|
||||||
AMICALE: "amicale",
|
AMICALE: 'amicale',
|
||||||
STUDENTS: "students",
|
STUDENTS: 'students',
|
||||||
INSA: "insa",
|
INSA: 'insa',
|
||||||
SPECIAL: "special",
|
SPECIAL: 'special',
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export type ServiceItemType = {
|
||||||
|
key: string,
|
||||||
|
title: string,
|
||||||
|
subtitle: string,
|
||||||
|
image: string,
|
||||||
|
onPress: () => void,
|
||||||
|
badgeFunction?: (dashboard: FullDashboardType) => number,
|
||||||
|
};
|
||||||
|
|
||||||
export type ServiceItem = {
|
export type ServiceCategoryType = {
|
||||||
key: string,
|
key: string,
|
||||||
title: string,
|
title: string,
|
||||||
subtitle: string,
|
subtitle: string,
|
||||||
image: string,
|
image: string | number,
|
||||||
onPress: () => void,
|
content: Array<ServiceItemType>,
|
||||||
badgeFunction?: (dashboard: fullDashboard) => number,
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export type ServiceCategory = {
|
|
||||||
key: string,
|
|
||||||
title: string,
|
|
||||||
subtitle: string,
|
|
||||||
image: string | number,
|
|
||||||
content: Array<ServiceItem>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default class ServicesManager {
|
export default class ServicesManager {
|
||||||
|
navigation: StackNavigationProp;
|
||||||
|
|
||||||
navigation: StackNavigationProp;
|
amicaleDataset: Array<ServiceItemType>;
|
||||||
|
|
||||||
amicaleDataset: Array<ServiceItem>;
|
studentsDataset: Array<ServiceItemType>;
|
||||||
studentsDataset: Array<ServiceItem>;
|
|
||||||
insaDataset: Array<ServiceItem>;
|
|
||||||
specialDataset: Array<ServiceItem>;
|
|
||||||
|
|
||||||
categoriesDataset: Array<ServiceCategory>;
|
insaDataset: Array<ServiceItemType>;
|
||||||
|
|
||||||
constructor(nav: StackNavigationProp) {
|
specialDataset: Array<ServiceItemType>;
|
||||||
this.navigation = nav;
|
|
||||||
this.amicaleDataset = [
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.CLUBS,
|
|
||||||
title: i18n.t('screens.clubs.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.clubs'),
|
|
||||||
image: CLUBS_IMAGE,
|
|
||||||
onPress: () => this.onAmicaleServicePress("club-list"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.PROFILE,
|
|
||||||
title: i18n.t('screens.profile.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.profile'),
|
|
||||||
image: PROFILE_IMAGE,
|
|
||||||
onPress: () => this.onAmicaleServicePress("profile"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.EQUIPMENT,
|
|
||||||
title: i18n.t('screens.equipment.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.equipment'),
|
|
||||||
image: EQUIPMENT_IMAGE,
|
|
||||||
onPress: () => this.onAmicaleServicePress("equipment-list"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.AMICALE_WEBSITE,
|
|
||||||
title: i18n.t('screens.websites.amicale'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.amicaleWebsite'),
|
|
||||||
image: AMICALE_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.AMICALE,
|
|
||||||
title: i18n.t('screens.websites.amicale')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.VOTE,
|
|
||||||
title: i18n.t('screens.vote.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.vote'),
|
|
||||||
image: VOTE_IMAGE,
|
|
||||||
onPress: () => this.onAmicaleServicePress("vote"),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.studentsDataset = [
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.PROXIMO,
|
|
||||||
title: i18n.t('screens.proximo.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.proximo'),
|
|
||||||
image: PROXIMO_IMAGE,
|
|
||||||
onPress: () => nav.navigate("proximo"),
|
|
||||||
badgeFunction: (dashboard: fullDashboard) => dashboard.proximo_articles
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.WIKETUD,
|
|
||||||
title: "Wiketud",
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.wiketud'),
|
|
||||||
image: WIKETUD_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.WIKETUD, title: "Wiketud"}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.ELUS_ETUDIANTS,
|
|
||||||
title: "Élus Étudiants",
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.elusEtudiants'),
|
|
||||||
image: EE_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.ELUS_ETUDIANTS,
|
|
||||||
title: "Élus Étudiants"
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.TUTOR_INSA,
|
|
||||||
title: "Tutor'INSA",
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.tutorInsa'),
|
|
||||||
image: TUTORINSA_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.TUTOR_INSA,
|
|
||||||
title: "Tutor'INSA"
|
|
||||||
}),
|
|
||||||
badgeFunction: (dashboard: fullDashboard) => dashboard.available_tutorials
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.insaDataset = [
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.RU,
|
|
||||||
title: i18n.t('screens.menu.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.self'),
|
|
||||||
image: RU_IMAGE,
|
|
||||||
onPress: () => nav.navigate("self-menu"),
|
|
||||||
badgeFunction: (dashboard: fullDashboard) => dashboard.today_menu.length
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.AVAILABLE_ROOMS,
|
|
||||||
title: i18n.t('screens.websites.rooms'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.availableRooms'),
|
|
||||||
image: ROOM_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.AVAILABLE_ROOMS,
|
|
||||||
title: i18n.t('screens.websites.rooms')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.BIB,
|
|
||||||
title: i18n.t('screens.websites.bib'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.bib'),
|
|
||||||
image: BIB_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.BIB,
|
|
||||||
title: i18n.t('screens.websites.bib')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.EMAIL,
|
|
||||||
title: i18n.t('screens.websites.mails'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.mails'),
|
|
||||||
image: EMAIL_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.BLUEMIND,
|
|
||||||
title: i18n.t('screens.websites.mails')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.ENT,
|
|
||||||
title: i18n.t('screens.websites.ent'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.ent'),
|
|
||||||
image: ENT_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.ENT,
|
|
||||||
title: i18n.t('screens.websites.ent')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.INSA_ACCOUNT,
|
|
||||||
title: i18n.t('screens.insaAccount.title'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.insaAccount'),
|
|
||||||
image: ACCOUNT_IMAGE,
|
|
||||||
onPress: () => nav.navigate("website", {
|
|
||||||
host: AvailableWebsites.websites.INSA_ACCOUNT,
|
|
||||||
title: i18n.t('screens.insaAccount.title')
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.specialDataset = [
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.WASHERS,
|
|
||||||
title: i18n.t('screens.proxiwash.washers'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.washers'),
|
|
||||||
image: WASHER_IMAGE,
|
|
||||||
onPress: () => nav.navigate("proxiwash"),
|
|
||||||
badgeFunction: (dashboard: fullDashboard) => dashboard.available_washers
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_KEY.DRYERS,
|
|
||||||
title: i18n.t('screens.proxiwash.dryers'),
|
|
||||||
subtitle: i18n.t('screens.services.descriptions.washers'),
|
|
||||||
image: DRYER_IMAGE,
|
|
||||||
onPress: () => nav.navigate("proxiwash"),
|
|
||||||
badgeFunction: (dashboard: fullDashboard) => dashboard.available_dryers
|
|
||||||
}
|
|
||||||
];
|
|
||||||
this.categoriesDataset = [
|
|
||||||
{
|
|
||||||
key: SERVICES_CATEGORIES_KEY.AMICALE,
|
|
||||||
title: i18n.t("screens.services.categories.amicale"),
|
|
||||||
subtitle: i18n.t("screens.services.more"),
|
|
||||||
image: AMICALE_LOGO,
|
|
||||||
content: this.amicaleDataset
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_CATEGORIES_KEY.STUDENTS,
|
|
||||||
title: i18n.t("screens.services.categories.students"),
|
|
||||||
subtitle: i18n.t("screens.services.more"),
|
|
||||||
image: 'account-group',
|
|
||||||
content: this.studentsDataset
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_CATEGORIES_KEY.INSA,
|
|
||||||
title: i18n.t("screens.services.categories.insa"),
|
|
||||||
subtitle: i18n.t("screens.services.more"),
|
|
||||||
image: 'school',
|
|
||||||
content: this.insaDataset
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SERVICES_CATEGORIES_KEY.SPECIAL,
|
|
||||||
title: i18n.t("screens.services.categories.special"),
|
|
||||||
subtitle: i18n.t("screens.services.categories.special"),
|
|
||||||
image: 'star',
|
|
||||||
content: this.specialDataset
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
categoriesDataset: Array<ServiceCategoryType>;
|
||||||
* Redirects the user to the login screen if he is not logged in
|
|
||||||
*
|
|
||||||
* @param route
|
|
||||||
* @returns {null}
|
|
||||||
*/
|
|
||||||
onAmicaleServicePress(route: string) {
|
|
||||||
if (ConnectionManager.getInstance().isLoggedIn())
|
|
||||||
this.navigation.navigate(route);
|
|
||||||
else
|
|
||||||
this.navigation.navigate("login", {nextScreen: route});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
constructor(nav: StackNavigationProp) {
|
||||||
* Gets the given services list without items of the given ids
|
this.navigation = nav;
|
||||||
*
|
this.amicaleDataset = [
|
||||||
* @param idList The ids of items to remove
|
{
|
||||||
* @param sourceList The item list to use as source
|
key: SERVICES_KEY.CLUBS,
|
||||||
* @returns {[]}
|
title: i18n.t('screens.clubs.title'),
|
||||||
*/
|
subtitle: i18n.t('screens.services.descriptions.clubs'),
|
||||||
getStrippedList(idList: Array<string>, sourceList: Array<{key: string, [key: string]: any}>) {
|
image: CLUBS_IMAGE,
|
||||||
let newArray = [];
|
onPress: (): void => this.onAmicaleServicePress('club-list'),
|
||||||
for (let i = 0; i < sourceList.length; i++) {
|
},
|
||||||
const item = sourceList[i];
|
{
|
||||||
if (!(idList.includes(item.key)))
|
key: SERVICES_KEY.PROFILE,
|
||||||
newArray.push(item);
|
title: i18n.t('screens.profile.title'),
|
||||||
}
|
subtitle: i18n.t('screens.services.descriptions.profile'),
|
||||||
return newArray;
|
image: PROFILE_IMAGE,
|
||||||
}
|
onPress: (): void => this.onAmicaleServicePress('profile'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.EQUIPMENT,
|
||||||
|
title: i18n.t('screens.equipment.title'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.equipment'),
|
||||||
|
image: EQUIPMENT_IMAGE,
|
||||||
|
onPress: (): void => this.onAmicaleServicePress('equipment-list'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.AMICALE_WEBSITE,
|
||||||
|
title: i18n.t('screens.websites.amicale'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.amicaleWebsite'),
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.AMICALE,
|
||||||
|
title: i18n.t('screens.websites.amicale'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.VOTE,
|
||||||
|
title: i18n.t('screens.vote.title'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.vote'),
|
||||||
|
image: VOTE_IMAGE,
|
||||||
|
onPress: (): void => this.onAmicaleServicePress('vote'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.studentsDataset = [
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.PROXIMO,
|
||||||
|
title: i18n.t('screens.proximo.title'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.proximo'),
|
||||||
|
image: PROXIMO_IMAGE,
|
||||||
|
onPress: (): void => nav.navigate('proximo'),
|
||||||
|
badgeFunction: (dashboard: FullDashboardType): number =>
|
||||||
|
dashboard.proximo_articles,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.WIKETUD,
|
||||||
|
title: 'Wiketud',
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.wiketud'),
|
||||||
|
image: WIKETUD_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.WIKETUD,
|
||||||
|
title: 'Wiketud',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.ELUS_ETUDIANTS,
|
||||||
|
title: 'Élus Étudiants',
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.elusEtudiants'),
|
||||||
|
image: EE_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.ELUS_ETUDIANTS,
|
||||||
|
title: 'Élus Étudiants',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.TUTOR_INSA,
|
||||||
|
title: "Tutor'INSA",
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.tutorInsa'),
|
||||||
|
image: TUTORINSA_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.TUTOR_INSA,
|
||||||
|
title: "Tutor'INSA",
|
||||||
|
}),
|
||||||
|
badgeFunction: (dashboard: FullDashboardType): number =>
|
||||||
|
dashboard.available_tutorials,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.insaDataset = [
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.RU,
|
||||||
|
title: i18n.t('screens.menu.title'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.self'),
|
||||||
|
image: RU_IMAGE,
|
||||||
|
onPress: (): void => nav.navigate('self-menu'),
|
||||||
|
badgeFunction: (dashboard: FullDashboardType): number =>
|
||||||
|
dashboard.today_menu.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.AVAILABLE_ROOMS,
|
||||||
|
title: i18n.t('screens.websites.rooms'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.availableRooms'),
|
||||||
|
image: ROOM_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.AVAILABLE_ROOMS,
|
||||||
|
title: i18n.t('screens.websites.rooms'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.BIB,
|
||||||
|
title: i18n.t('screens.websites.bib'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.bib'),
|
||||||
|
image: BIB_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.BIB,
|
||||||
|
title: i18n.t('screens.websites.bib'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.EMAIL,
|
||||||
|
title: i18n.t('screens.websites.mails'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.mails'),
|
||||||
|
image: EMAIL_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.BLUEMIND,
|
||||||
|
title: i18n.t('screens.websites.mails'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.ENT,
|
||||||
|
title: i18n.t('screens.websites.ent'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.ent'),
|
||||||
|
image: ENT_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.ENT,
|
||||||
|
title: i18n.t('screens.websites.ent'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.INSA_ACCOUNT,
|
||||||
|
title: i18n.t('screens.insaAccount.title'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.insaAccount'),
|
||||||
|
image: ACCOUNT_IMAGE,
|
||||||
|
onPress: (): void =>
|
||||||
|
nav.navigate('website', {
|
||||||
|
host: AvailableWebsites.websites.INSA_ACCOUNT,
|
||||||
|
title: i18n.t('screens.insaAccount.title'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.specialDataset = [
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.WASHERS,
|
||||||
|
title: i18n.t('screens.proxiwash.washers'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.washers'),
|
||||||
|
image: WASHER_IMAGE,
|
||||||
|
onPress: (): void => nav.navigate('proxiwash'),
|
||||||
|
badgeFunction: (dashboard: FullDashboardType): number =>
|
||||||
|
dashboard.available_washers,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_KEY.DRYERS,
|
||||||
|
title: i18n.t('screens.proxiwash.dryers'),
|
||||||
|
subtitle: i18n.t('screens.services.descriptions.washers'),
|
||||||
|
image: DRYER_IMAGE,
|
||||||
|
onPress: (): void => nav.navigate('proxiwash'),
|
||||||
|
badgeFunction: (dashboard: FullDashboardType): number =>
|
||||||
|
dashboard.available_dryers,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.categoriesDataset = [
|
||||||
|
{
|
||||||
|
key: SERVICES_CATEGORIES_KEY.AMICALE,
|
||||||
|
title: i18n.t('screens.services.categories.amicale'),
|
||||||
|
subtitle: i18n.t('screens.services.more'),
|
||||||
|
image: AMICALE_LOGO,
|
||||||
|
content: this.amicaleDataset,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_CATEGORIES_KEY.STUDENTS,
|
||||||
|
title: i18n.t('screens.services.categories.students'),
|
||||||
|
subtitle: i18n.t('screens.services.more'),
|
||||||
|
image: 'account-group',
|
||||||
|
content: this.studentsDataset,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_CATEGORIES_KEY.INSA,
|
||||||
|
title: i18n.t('screens.services.categories.insa'),
|
||||||
|
subtitle: i18n.t('screens.services.more'),
|
||||||
|
image: 'school',
|
||||||
|
content: this.insaDataset,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SERVICES_CATEGORIES_KEY.SPECIAL,
|
||||||
|
title: i18n.t('screens.services.categories.special'),
|
||||||
|
subtitle: i18n.t('screens.services.categories.special'),
|
||||||
|
image: 'star',
|
||||||
|
content: this.specialDataset,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of amicale's services
|
* Redirects the user to the login screen if he is not logged in
|
||||||
*
|
*
|
||||||
* @param excludedItems Ids of items to exclude from the returned list
|
* @param route
|
||||||
* @returns {Array<ServiceItem>}
|
* @returns {null}
|
||||||
*/
|
*/
|
||||||
getAmicaleServices(excludedItems?: Array<string>) {
|
onAmicaleServicePress(route: string) {
|
||||||
if (excludedItems != null)
|
if (ConnectionManager.getInstance().isLoggedIn())
|
||||||
return this.getStrippedList(excludedItems, this.amicaleDataset)
|
this.navigation.navigate(route);
|
||||||
else
|
else this.navigation.navigate('login', {nextScreen: route});
|
||||||
return this.amicaleDataset;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of students' services
|
* Gets the list of amicale's services
|
||||||
*
|
*
|
||||||
* @param excludedItems Ids of items to exclude from the returned list
|
* @param excludedItems Ids of items to exclude from the returned list
|
||||||
* @returns {Array<ServiceItem>}
|
* @returns {Array<ServiceItemType>}
|
||||||
*/
|
*/
|
||||||
getStudentServices(excludedItems?: Array<string>) {
|
getAmicaleServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||||
if (excludedItems != null)
|
if (excludedItems != null)
|
||||||
return this.getStrippedList(excludedItems, this.studentsDataset)
|
return getStrippedServicesList(excludedItems, this.amicaleDataset);
|
||||||
else
|
return this.amicaleDataset;
|
||||||
return this.studentsDataset;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of INSA's services
|
* Gets the list of students' services
|
||||||
*
|
*
|
||||||
* @param excludedItems Ids of items to exclude from the returned list
|
* @param excludedItems Ids of items to exclude from the returned list
|
||||||
* @returns {Array<ServiceItem>}
|
* @returns {Array<ServiceItemType>}
|
||||||
*/
|
*/
|
||||||
getINSAServices(excludedItems?: Array<string>) {
|
getStudentServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||||
if (excludedItems != null)
|
if (excludedItems != null)
|
||||||
return this.getStrippedList(excludedItems, this.insaDataset)
|
return getStrippedServicesList(excludedItems, this.studentsDataset);
|
||||||
else
|
return this.studentsDataset;
|
||||||
return this.insaDataset;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of special services
|
* Gets the list of INSA's services
|
||||||
*
|
*
|
||||||
* @param excludedItems Ids of items to exclude from the returned list
|
* @param excludedItems Ids of items to exclude from the returned list
|
||||||
* @returns {Array<ServiceItem>}
|
* @returns {Array<ServiceItemType>}
|
||||||
*/
|
*/
|
||||||
getSpecialServices(excludedItems?: Array<string>) {
|
getINSAServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||||
if (excludedItems != null)
|
if (excludedItems != null)
|
||||||
return this.getStrippedList(excludedItems, this.specialDataset)
|
return getStrippedServicesList(excludedItems, this.insaDataset);
|
||||||
else
|
return this.insaDataset;
|
||||||
return this.specialDataset;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all services sorted by category
|
* Gets the list of special services
|
||||||
*
|
*
|
||||||
* @param excludedItems Ids of categories to exclude from the returned list
|
* @param excludedItems Ids of items to exclude from the returned list
|
||||||
* @returns {Array<ServiceCategory>}
|
* @returns {Array<ServiceItemType>}
|
||||||
*/
|
*/
|
||||||
getCategories(excludedItems?: Array<string>) {
|
getSpecialServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||||
if (excludedItems != null)
|
if (excludedItems != null)
|
||||||
return this.getStrippedList(excludedItems, this.categoriesDataset)
|
return getStrippedServicesList(excludedItems, this.specialDataset);
|
||||||
else
|
return this.specialDataset;
|
||||||
return this.categoriesDataset;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all services sorted by category
|
||||||
|
*
|
||||||
|
* @param excludedItems Ids of categories to exclude from the returned list
|
||||||
|
* @returns {Array<ServiceCategoryType>}
|
||||||
|
*/
|
||||||
|
getCategories(excludedItems?: Array<string>): Array<ServiceCategoryType> {
|
||||||
|
if (excludedItems != null)
|
||||||
|
return getStrippedServicesList(excludedItems, this.categoriesDataset);
|
||||||
|
return this.categoriesDataset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import AsyncStorageManager from '../../managers/AsyncStorageManager';
|
||||||
import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
|
import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
|
||||||
import MascotPopup from '../../components/Mascot/MascotPopup';
|
import MascotPopup from '../../components/Mascot/MascotPopup';
|
||||||
import DashboardManager from '../../managers/DashboardManager';
|
import DashboardManager from '../../managers/DashboardManager';
|
||||||
import type {ServiceItem} from '../../managers/ServicesManager';
|
import type {ServiceItemType} from '../../managers/ServicesManager';
|
||||||
import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
|
import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param content
|
* @param content
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getDashboardRow(content: Array<ServiceItem | null>): React.Node {
|
getDashboardRow(content: Array<ServiceItemType | null>): React.Node {
|
||||||
return (
|
return (
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
<FlatList
|
<FlatList
|
||||||
|
@ -256,7 +256,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
||||||
getDashboardRowRenderItem = ({
|
getDashboardRowRenderItem = ({
|
||||||
item,
|
item,
|
||||||
}: {
|
}: {
|
||||||
item: ServiceItem | null,
|
item: ServiceItemType | null,
|
||||||
}): React.Node => {
|
}): React.Node => {
|
||||||
if (item != null)
|
if (item != null)
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,149 +1,162 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type {cardList} from "../../components/Lists/CardList/CardList";
|
import {Image, View} from 'react-native';
|
||||||
import CardList from "../../components/Lists/CardList/CardList";
|
import {
|
||||||
import {Image, View} from "react-native";
|
Avatar,
|
||||||
import {Avatar, Card, Divider, List, TouchableRipple, withTheme} from "react-native-paper";
|
Card,
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
Divider,
|
||||||
|
List,
|
||||||
|
TouchableRipple,
|
||||||
|
withTheme,
|
||||||
|
} from 'react-native-paper';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
import {StackNavigationProp} from '@react-navigation/stack';
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import CardList from '../../components/Lists/CardList/CardList';
|
||||||
import {MASCOT_STYLE} from "../../components/Mascot/Mascot";
|
import type {CustomTheme} from '../../managers/ThemeManager';
|
||||||
import MascotPopup from "../../components/Mascot/MascotPopup";
|
import MaterialHeaderButtons, {
|
||||||
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
Item,
|
||||||
import ServicesManager, {SERVICES_CATEGORIES_KEY} from "../../managers/ServicesManager";
|
} from '../../components/Overrides/CustomHeaderButton';
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
|
||||||
|
import MascotPopup from '../../components/Mascot/MascotPopup';
|
||||||
|
import AsyncStorageManager from '../../managers/AsyncStorageManager';
|
||||||
|
import ServicesManager, {
|
||||||
|
SERVICES_CATEGORIES_KEY,
|
||||||
|
} from '../../managers/ServicesManager';
|
||||||
|
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
|
||||||
|
import type {ServiceCategoryType} from '../../managers/ServicesManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
};
|
||||||
|
|
||||||
export type listItem = {
|
class ServicesScreen extends React.Component<PropsType> {
|
||||||
title: string,
|
finalDataset: Array<ServiceCategoryType>;
|
||||||
description: string,
|
|
||||||
image: string | number,
|
|
||||||
content: cardList,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
constructor(props: PropsType) {
|
||||||
|
super(props);
|
||||||
|
const services = new ServicesManager(props.navigation);
|
||||||
|
this.finalDataset = services.getCategories([
|
||||||
|
SERVICES_CATEGORIES_KEY.SPECIAL,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
class ServicesScreen extends React.Component<Props> {
|
componentDidMount() {
|
||||||
|
const {props} = this;
|
||||||
|
props.navigation.setOptions({
|
||||||
|
headerRight: this.getAboutButton,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
finalDataset: Array<listItem>
|
getAboutButton = (): React.Node => (
|
||||||
|
<MaterialHeaderButtons>
|
||||||
|
<Item
|
||||||
|
title="information"
|
||||||
|
iconName="information"
|
||||||
|
onPress={this.onAboutPress}
|
||||||
|
/>
|
||||||
|
</MaterialHeaderButtons>
|
||||||
|
);
|
||||||
|
|
||||||
constructor(props) {
|
onAboutPress = () => {
|
||||||
super(props);
|
const {props} = this;
|
||||||
const services = new ServicesManager(props.navigation);
|
props.navigation.navigate('amicale-contact');
|
||||||
this.finalDataset = services.getCategories([SERVICES_CATEGORIES_KEY.SPECIAL])
|
};
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
/**
|
||||||
this.props.navigation.setOptions({
|
* Gets the list title image for the list.
|
||||||
headerRight: this.getAboutButton,
|
*
|
||||||
});
|
* If the source is a string, we are using an icon.
|
||||||
}
|
* If the source is a number, we are using an internal image.
|
||||||
|
*
|
||||||
|
* @param source The source image to display. Can be a string for icons or a number for local images
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
getListTitleImage(source: string | number): React.Node {
|
||||||
|
const {props} = this;
|
||||||
|
if (typeof source === 'number')
|
||||||
|
return (
|
||||||
|
<Image
|
||||||
|
size={48}
|
||||||
|
source={source}
|
||||||
|
style={{
|
||||||
|
width: 48,
|
||||||
|
height: 48,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Avatar.Icon
|
||||||
|
size={48}
|
||||||
|
icon={source}
|
||||||
|
color={props.theme.colors.primary}
|
||||||
|
style={{backgroundColor: 'transparent'}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getAboutButton = () =>
|
/**
|
||||||
<MaterialHeaderButtons>
|
* A list item showing a list of available services for the current category
|
||||||
<Item title="information" iconName="information" onPress={this.onAboutPress}/>
|
*
|
||||||
</MaterialHeaderButtons>;
|
* @param item
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => {
|
||||||
|
const {props} = this;
|
||||||
|
return (
|
||||||
|
<TouchableRipple
|
||||||
|
style={{
|
||||||
|
margin: 5,
|
||||||
|
marginBottom: 20,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
props.navigation.navigate('services-section', {data: item});
|
||||||
|
}}>
|
||||||
|
<View>
|
||||||
|
<Card.Title
|
||||||
|
title={item.title}
|
||||||
|
subtitle={item.subtitle}
|
||||||
|
left={(): React.Node => this.getListTitleImage(item.image)}
|
||||||
|
right={({size}: {size: number}): React.Node => (
|
||||||
|
<List.Icon size={size} icon="chevron-right" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<CardList dataset={item.content} isHorizontal />
|
||||||
|
</View>
|
||||||
|
</TouchableRipple>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
onAboutPress = () => this.props.navigation.navigate('amicale-contact');
|
keyExtractor = (item: ServiceCategoryType): string => item.title;
|
||||||
|
|
||||||
/**
|
render(): React.Node {
|
||||||
* Gets the list title image for the list.
|
return (
|
||||||
*
|
<View>
|
||||||
* If the source is a string, we are using an icon.
|
<CollapsibleFlatList
|
||||||
* If the source is a number, we are using an internal image.
|
data={this.finalDataset}
|
||||||
*
|
renderItem={this.getRenderItem}
|
||||||
* @param props Props to pass to the component
|
keyExtractor={this.keyExtractor}
|
||||||
* @param source The source image to display. Can be a string for icons or a number for local images
|
ItemSeparatorComponent={(): React.Node => <Divider />}
|
||||||
* @returns {*}
|
hasTab
|
||||||
*/
|
/>
|
||||||
getListTitleImage(props, source: string | number) {
|
<MascotPopup
|
||||||
if (typeof source === "number")
|
prefKey={AsyncStorageManager.PREFERENCES.servicesShowBanner.key}
|
||||||
return <Image
|
title={i18n.t('screens.services.mascotDialog.title')}
|
||||||
size={48}
|
message={i18n.t('screens.services.mascotDialog.message')}
|
||||||
source={source}
|
icon="cloud-question"
|
||||||
style={{
|
buttons={{
|
||||||
width: 48,
|
action: null,
|
||||||
height: 48,
|
cancel: {
|
||||||
}}/>
|
message: i18n.t('screens.services.mascotDialog.button'),
|
||||||
else
|
icon: 'check',
|
||||||
return <Avatar.Icon
|
},
|
||||||
{...props}
|
}}
|
||||||
size={48}
|
emotion={MASCOT_STYLE.WINK}
|
||||||
icon={source}
|
/>
|
||||||
color={this.props.theme.colors.primary}
|
</View>
|
||||||
style={{backgroundColor: 'transparent'}}
|
);
|
||||||
/>
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list item showing a list of available services for the current category
|
|
||||||
*
|
|
||||||
* @param item
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
renderItem = ({item}: { item: listItem }) => {
|
|
||||||
return (
|
|
||||||
<TouchableRipple
|
|
||||||
style={{
|
|
||||||
margin: 5,
|
|
||||||
marginBottom: 20,
|
|
||||||
}}
|
|
||||||
onPress={() => this.props.navigation.navigate("services-section", {data: item})}
|
|
||||||
>
|
|
||||||
<View>
|
|
||||||
<Card.Title
|
|
||||||
title={item.title}
|
|
||||||
subtitle={item.description}
|
|
||||||
left={(props) => this.getListTitleImage(props, item.image)}
|
|
||||||
right={(props) => <List.Icon {...props} icon="chevron-right"/>}
|
|
||||||
/>
|
|
||||||
<CardList
|
|
||||||
dataset={item.content}
|
|
||||||
isHorizontal={true}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</TouchableRipple>
|
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
keyExtractor = (item: listItem) => {
|
|
||||||
return item.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<View>
|
|
||||||
<CollapsibleFlatList
|
|
||||||
data={this.finalDataset}
|
|
||||||
renderItem={this.renderItem}
|
|
||||||
keyExtractor={this.keyExtractor}
|
|
||||||
ItemSeparatorComponent={() => <Divider/>}
|
|
||||||
hasTab={true}
|
|
||||||
/>
|
|
||||||
<MascotPopup
|
|
||||||
prefKey={AsyncStorageManager.PREFERENCES.servicesShowBanner.key}
|
|
||||||
title={i18n.t("screens.services.mascotDialog.title")}
|
|
||||||
message={i18n.t("screens.services.mascotDialog.message")}
|
|
||||||
icon={"cloud-question"}
|
|
||||||
buttons={{
|
|
||||||
action: null,
|
|
||||||
cancel: {
|
|
||||||
message: i18n.t("screens.services.mascotDialog.button"),
|
|
||||||
icon: "check",
|
|
||||||
onPress: this.onHideMascotDialog,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
emotion={MASCOT_STYLE.WINK}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(ServicesScreen);
|
export default withTheme(ServicesScreen);
|
||||||
|
|
|
@ -1,58 +1,65 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import CardList from "../../components/Lists/CardList/CardList";
|
import {Collapsible} from 'react-navigation-collapsible';
|
||||||
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
import {CommonActions} from '@react-navigation/native';
|
||||||
import {withCollapsible} from "../../utils/withCollapsible";
|
import {StackNavigationProp} from '@react-navigation/stack';
|
||||||
import {Collapsible} from "react-navigation-collapsible";
|
import CardList from '../../components/Lists/CardList/CardList';
|
||||||
import {CommonActions} from "@react-navigation/native";
|
import CustomTabBar from '../../components/Tabbar/CustomTabBar';
|
||||||
import type {listItem} from "./ServicesScreen";
|
import {withCollapsible} from '../../utils/withCollapsible';
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import type {ServiceCategoryType} from '../../managers/ServicesManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
route: { params: { data: listItem | null } },
|
route: {params: {data: ServiceCategoryType | null}},
|
||||||
collapsibleStack: Collapsible,
|
collapsibleStack: Collapsible,
|
||||||
}
|
};
|
||||||
|
|
||||||
class ServicesSectionScreen extends React.Component<Props> {
|
class ServicesSectionScreen extends React.Component<PropsType> {
|
||||||
|
finalDataset: ServiceCategoryType;
|
||||||
|
|
||||||
finalDataset: listItem;
|
constructor(props: PropsType) {
|
||||||
|
super(props);
|
||||||
|
this.handleNavigationParams();
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
/**
|
||||||
super(props);
|
* Recover the list to display from navigation parameters
|
||||||
this.handleNavigationParams();
|
*/
|
||||||
|
handleNavigationParams() {
|
||||||
|
const {props} = this;
|
||||||
|
if (props.route.params != null) {
|
||||||
|
if (props.route.params.data != null) {
|
||||||
|
this.finalDataset = props.route.params.data;
|
||||||
|
// reset params to prevent infinite loop
|
||||||
|
props.navigation.dispatch(CommonActions.setParams({data: null}));
|
||||||
|
props.navigation.setOptions({
|
||||||
|
headerTitle: this.finalDataset.title,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
render(): React.Node {
|
||||||
* Recover the list to display from navigation parameters
|
const {props} = this;
|
||||||
*/
|
const {
|
||||||
handleNavigationParams() {
|
containerPaddingTop,
|
||||||
if (this.props.route.params != null) {
|
scrollIndicatorInsetTop,
|
||||||
if (this.props.route.params.data != null) {
|
onScroll,
|
||||||
this.finalDataset = this.props.route.params.data;
|
} = props.collapsibleStack;
|
||||||
// reset params to prevent infinite loop
|
return (
|
||||||
this.props.navigation.dispatch(CommonActions.setParams({data: null}));
|
<CardList
|
||||||
this.props.navigation.setOptions({
|
dataset={this.finalDataset.content}
|
||||||
headerTitle: this.finalDataset.title,
|
isHorizontal={false}
|
||||||
});
|
onScroll={onScroll}
|
||||||
}
|
contentContainerStyle={{
|
||||||
}
|
paddingTop: containerPaddingTop,
|
||||||
}
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20,
|
||||||
|
}}
|
||||||
render() {
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
/>
|
||||||
return <CardList
|
);
|
||||||
dataset={this.finalDataset.content}
|
}
|
||||||
isHorizontal={false}
|
|
||||||
onScroll={onScroll}
|
|
||||||
contentContainerStyle={{
|
|
||||||
paddingTop: containerPaddingTop,
|
|
||||||
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
|
|
||||||
}}
|
|
||||||
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withCollapsible(ServicesSectionScreen);
|
export default withCollapsible(ServicesSectionScreen);
|
||||||
|
|
19
src/utils/Services.js
Normal file
19
src/utils/Services.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the given services list without items of the given ids
|
||||||
|
*
|
||||||
|
* @param idList The ids of items to remove
|
||||||
|
* @param sourceList The item list to use as source
|
||||||
|
* @returns {[]}
|
||||||
|
*/
|
||||||
|
export default function getStrippedServicesList<T>(
|
||||||
|
idList: Array<string>,
|
||||||
|
sourceList: Array<{key: string, ...T}>,
|
||||||
|
): Array<{key: string, ...T}> {
|
||||||
|
const newArray = [];
|
||||||
|
sourceList.forEach((item: {key: string, ...T}) => {
|
||||||
|
if (!idList.includes(item.key)) newArray.push(item);
|
||||||
|
});
|
||||||
|
return newArray;
|
||||||
|
}
|
Loading…
Reference in a new issue