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
|
||||
|
||||
import * as React from 'react';
|
||||
import {Animated, Dimensions} from "react-native";
|
||||
import ImageListItem from "./ImageListItem";
|
||||
import CardListItem from "./CardListItem";
|
||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
import {Animated, Dimensions} from 'react-native';
|
||||
import type {ViewStyle} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
import ImageListItem from './ImageListItem';
|
||||
import CardListItem from './CardListItem';
|
||||
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||
|
||||
type Props = {
|
||||
dataset: Array<cardItem>,
|
||||
isHorizontal: boolean,
|
||||
contentContainerStyle?: ViewStyle,
|
||||
}
|
||||
|
||||
export type cardItem = {
|
||||
key: string,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
image: string | number,
|
||||
onPress: () => void,
|
||||
type PropsType = {
|
||||
dataset: Array<ServiceItemType>,
|
||||
isHorizontal?: boolean,
|
||||
contentContainerStyle?: ViewStyle | null,
|
||||
};
|
||||
|
||||
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 = {
|
||||
isHorizontal: false,
|
||||
constructor(props: PropsType) {
|
||||
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',
|
||||
};
|
||||
}
|
||||
|
||||
windowWidth: number;
|
||||
horizontalItemSize: number;
|
||||
|
||||
constructor(props: Props) {
|
||||
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
|
||||
}
|
||||
|
||||
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 (
|
||||
<Animated.FlatList
|
||||
data={props.dataset}
|
||||
renderItem={this.getRenderItem}
|
||||
keyExtractor={this.keyExtractor}
|
||||
numColumns={props.isHorizontal ? undefined : 2}
|
||||
horizontal={props.isHorizontal}
|
||||
contentContainerStyle={
|
||||
props.isHorizontal ? containerStyle : props.contentContainerStyle
|
||||
}
|
||||
return (
|
||||
<Animated.FlatList
|
||||
{...this.props}
|
||||
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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
pagingEnabled={props.isHorizontal}
|
||||
snapToInterval={
|
||||
props.isHorizontal ? (this.horizontalItemSize + 5) * 3 : null
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,50 +2,41 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import {Caption, Card, Paragraph, TouchableRipple} from 'react-native-paper';
|
||||
import {View} from "react-native";
|
||||
import type {cardItem} from "./CardList";
|
||||
import {View} from 'react-native';
|
||||
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||
|
||||
type Props = {
|
||||
item: cardItem,
|
||||
}
|
||||
|
||||
export default class CardListItem extends React.Component<Props> {
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const item = props.item;
|
||||
const source = typeof item.image === "number"
|
||||
? item.image
|
||||
: {uri: item.image};
|
||||
return (
|
||||
<Card
|
||||
style={{
|
||||
width: '40%',
|
||||
margin: 5,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}
|
||||
>
|
||||
<TouchableRipple
|
||||
style={{flex: 1}}
|
||||
onPress={item.onPress}>
|
||||
<View>
|
||||
<Card.Cover
|
||||
style={{height: 80}}
|
||||
source={source}
|
||||
/>
|
||||
<Card.Content>
|
||||
<Paragraph>{item.title}</Paragraph>
|
||||
<Caption>{item.subtitle}</Caption>
|
||||
</Card.Content>
|
||||
</View>
|
||||
</TouchableRipple>
|
||||
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
type PropsType = {
|
||||
item: ServiceItemType,
|
||||
};
|
||||
|
||||
export default class CardListItem extends React.Component<PropsType> {
|
||||
shouldComponentUpdate(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
const {item} = props;
|
||||
const source =
|
||||
typeof item.image === 'number' ? item.image : {uri: item.image};
|
||||
return (
|
||||
<Card
|
||||
style={{
|
||||
width: '40%',
|
||||
margin: 5,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}>
|
||||
<TouchableRipple style={{flex: 1}} onPress={item.onPress}>
|
||||
<View>
|
||||
<Card.Cover style={{height: 80}} source={source} />
|
||||
<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 {Text, TouchableRipple} from 'react-native-paper';
|
||||
import {Image, View} from 'react-native';
|
||||
import type {cardItem} from "./CardList";
|
||||
import type {ServiceItemType} from '../../../managers/ServicesManager';
|
||||
|
||||
type Props = {
|
||||
item: cardItem,
|
||||
width: number,
|
||||
}
|
||||
|
||||
export default class ImageListItem extends React.Component<Props> {
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const item = this.props.item;
|
||||
const source = typeof item.image === "number"
|
||||
? item.image
|
||||
: {uri: item.image};
|
||||
return (
|
||||
<TouchableRipple
|
||||
style={{
|
||||
width: this.props.width,
|
||||
height: this.props.width + 40,
|
||||
margin: 5,
|
||||
}}
|
||||
onPress={item.onPress}
|
||||
>
|
||||
<View>
|
||||
<Image
|
||||
style={{
|
||||
width: this.props.width - 20,
|
||||
height: this.props.width - 20,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}
|
||||
source={source}
|
||||
/>
|
||||
<Text style={{
|
||||
marginTop: 5,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableRipple>
|
||||
);
|
||||
}
|
||||
type PropsType = {
|
||||
item: ServiceItemType,
|
||||
width: number,
|
||||
};
|
||||
|
||||
export default class ImageListItem extends React.Component<PropsType> {
|
||||
shouldComponentUpdate(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
const {item} = props;
|
||||
const source =
|
||||
typeof item.image === 'number' ? item.image : {uri: item.image};
|
||||
return (
|
||||
<TouchableRipple
|
||||
style={{
|
||||
width: props.width,
|
||||
height: props.width + 40,
|
||||
margin: 5,
|
||||
}}
|
||||
onPress={item.onPress}>
|
||||
<View>
|
||||
<Image
|
||||
style={{
|
||||
width: props.width - 20,
|
||||
height: props.width - 20,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}
|
||||
source={source}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
marginTop: 5,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableRipple>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import type {ServiceItem} from './ServicesManager';
|
||||
import type {ServiceItemType} from './ServicesManager';
|
||||
import ServicesManager from './ServicesManager';
|
||||
import {getSublistWithIds} from '../utils/Utils';
|
||||
import AsyncStorageManager from './AsyncStorageManager';
|
||||
|
||||
export default class DashboardManager extends ServicesManager {
|
||||
getCurrentDashboard(): Array<ServiceItem | null> {
|
||||
getCurrentDashboard(): Array<ServiceItemType | null> {
|
||||
const dashboardIdList = AsyncStorageManager.getObject(
|
||||
AsyncStorageManager.PREFERENCES.dashboardItems.key,
|
||||
);
|
||||
|
|
|
@ -1,378 +1,384 @@
|
|||
// @flow
|
||||
|
||||
import i18n from "i18n-js";
|
||||
import AvailableWebsites from "../constants/AvailableWebsites";
|
||||
import {StackNavigationProp} from "@react-navigation/stack";
|
||||
import ConnectionManager from "./ConnectionManager";
|
||||
import type {fullDashboard} from "../screens/Home/HomeScreen";
|
||||
import i18n from 'i18n-js';
|
||||
import {StackNavigationProp} from '@react-navigation/stack';
|
||||
import AvailableWebsites from '../constants/AvailableWebsites';
|
||||
import ConnectionManager from './ConnectionManager';
|
||||
import type {FullDashboardType} from '../screens/Home/HomeScreen';
|
||||
import getStrippedServicesList from '../utils/Services';
|
||||
|
||||
// AMICALE
|
||||
const CLUBS_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Clubs.png";
|
||||
const PROFILE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProfilAmicaliste.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";
|
||||
const CLUBS_IMAGE =
|
||||
'https://etud.insa-toulouse.fr/~amicale_app/images/Clubs.png';
|
||||
const PROFILE_IMAGE =
|
||||
'https://etud.insa-toulouse.fr/~amicale_app/images/ProfilAmicaliste.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
|
||||
const PROXIMO_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png"
|
||||
const WIKETUD_IMAGE = "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";
|
||||
const PROXIMO_IMAGE =
|
||||
'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
|
||||
const WIKETUD_IMAGE =
|
||||
'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
|
||||
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 ROOM_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Salles.png";
|
||||
const EMAIL_IMAGE = "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";
|
||||
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 ROOM_IMAGE =
|
||||
'https://etud.insa-toulouse.fr/~amicale_app/images/Salles.png';
|
||||
const EMAIL_IMAGE =
|
||||
'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
|
||||
const WASHER_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashLaveLinge.png";
|
||||
const DRYER_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProxiwashSecheLinge.png";
|
||||
const WASHER_IMAGE =
|
||||
'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 = {
|
||||
CLUBS: "clubs",
|
||||
PROFILE: "profile",
|
||||
EQUIPMENT: "equipment",
|
||||
AMICALE_WEBSITE: "amicale_website",
|
||||
VOTE: "vote",
|
||||
PROXIMO: "proximo",
|
||||
WIKETUD: "wiketud",
|
||||
ELUS_ETUDIANTS: "elus_etudiants",
|
||||
TUTOR_INSA: "tutor_insa",
|
||||
RU: "ru",
|
||||
AVAILABLE_ROOMS: "available_rooms",
|
||||
BIB: "bib",
|
||||
EMAIL: "email",
|
||||
ENT: "ent",
|
||||
INSA_ACCOUNT: "insa_account",
|
||||
WASHERS: "washers",
|
||||
DRYERS: "dryers",
|
||||
}
|
||||
CLUBS: 'clubs',
|
||||
PROFILE: 'profile',
|
||||
EQUIPMENT: 'equipment',
|
||||
AMICALE_WEBSITE: 'amicale_website',
|
||||
VOTE: 'vote',
|
||||
PROXIMO: 'proximo',
|
||||
WIKETUD: 'wiketud',
|
||||
ELUS_ETUDIANTS: 'elus_etudiants',
|
||||
TUTOR_INSA: 'tutor_insa',
|
||||
RU: 'ru',
|
||||
AVAILABLE_ROOMS: 'available_rooms',
|
||||
BIB: 'bib',
|
||||
EMAIL: 'email',
|
||||
ENT: 'ent',
|
||||
INSA_ACCOUNT: 'insa_account',
|
||||
WASHERS: 'washers',
|
||||
DRYERS: 'dryers',
|
||||
};
|
||||
|
||||
export const SERVICES_CATEGORIES_KEY = {
|
||||
AMICALE: "amicale",
|
||||
STUDENTS: "students",
|
||||
INSA: "insa",
|
||||
SPECIAL: "special",
|
||||
}
|
||||
AMICALE: 'amicale',
|
||||
STUDENTS: 'students',
|
||||
INSA: 'insa',
|
||||
SPECIAL: 'special',
|
||||
};
|
||||
|
||||
export type ServiceItemType = {
|
||||
key: string,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
image: string,
|
||||
onPress: () => void,
|
||||
badgeFunction?: (dashboard: FullDashboardType) => number,
|
||||
};
|
||||
|
||||
export type ServiceItem = {
|
||||
key: string,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
image: string,
|
||||
onPress: () => void,
|
||||
badgeFunction?: (dashboard: fullDashboard) => number,
|
||||
}
|
||||
|
||||
export type ServiceCategory = {
|
||||
key: string,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
image: string | number,
|
||||
content: Array<ServiceItem>
|
||||
}
|
||||
|
||||
export type ServiceCategoryType = {
|
||||
key: string,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
image: string | number,
|
||||
content: Array<ServiceItemType>,
|
||||
};
|
||||
|
||||
export default class ServicesManager {
|
||||
navigation: StackNavigationProp;
|
||||
|
||||
navigation: StackNavigationProp;
|
||||
amicaleDataset: Array<ServiceItemType>;
|
||||
|
||||
amicaleDataset: Array<ServiceItem>;
|
||||
studentsDataset: Array<ServiceItem>;
|
||||
insaDataset: Array<ServiceItem>;
|
||||
specialDataset: Array<ServiceItem>;
|
||||
studentsDataset: Array<ServiceItemType>;
|
||||
|
||||
categoriesDataset: Array<ServiceCategory>;
|
||||
insaDataset: Array<ServiceItemType>;
|
||||
|
||||
constructor(nav: StackNavigationProp) {
|
||||
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
|
||||
},
|
||||
];
|
||||
}
|
||||
specialDataset: Array<ServiceItemType>;
|
||||
|
||||
/**
|
||||
* 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});
|
||||
}
|
||||
categoriesDataset: Array<ServiceCategoryType>;
|
||||
|
||||
/**
|
||||
* 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 {[]}
|
||||
*/
|
||||
getStrippedList(idList: Array<string>, sourceList: Array<{key: string, [key: string]: any}>) {
|
||||
let newArray = [];
|
||||
for (let i = 0; i < sourceList.length; i++) {
|
||||
const item = sourceList[i];
|
||||
if (!(idList.includes(item.key)))
|
||||
newArray.push(item);
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
constructor(nav: StackNavigationProp) {
|
||||
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: (): void => 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: (): 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
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItem>}
|
||||
*/
|
||||
getAmicaleServices(excludedItems?: Array<string>) {
|
||||
if (excludedItems != null)
|
||||
return this.getStrippedList(excludedItems, this.amicaleDataset)
|
||||
else
|
||||
return this.amicaleDataset;
|
||||
}
|
||||
/**
|
||||
* 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});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of students' services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItem>}
|
||||
*/
|
||||
getStudentServices(excludedItems?: Array<string>) {
|
||||
if (excludedItems != null)
|
||||
return this.getStrippedList(excludedItems, this.studentsDataset)
|
||||
else
|
||||
return this.studentsDataset;
|
||||
}
|
||||
/**
|
||||
* Gets the list of amicale's services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItemType>}
|
||||
*/
|
||||
getAmicaleServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||
if (excludedItems != null)
|
||||
return getStrippedServicesList(excludedItems, this.amicaleDataset);
|
||||
return this.amicaleDataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of INSA's services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItem>}
|
||||
*/
|
||||
getINSAServices(excludedItems?: Array<string>) {
|
||||
if (excludedItems != null)
|
||||
return this.getStrippedList(excludedItems, this.insaDataset)
|
||||
else
|
||||
return this.insaDataset;
|
||||
}
|
||||
/**
|
||||
* Gets the list of students' services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItemType>}
|
||||
*/
|
||||
getStudentServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||
if (excludedItems != null)
|
||||
return getStrippedServicesList(excludedItems, this.studentsDataset);
|
||||
return this.studentsDataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of special services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItem>}
|
||||
*/
|
||||
getSpecialServices(excludedItems?: Array<string>) {
|
||||
if (excludedItems != null)
|
||||
return this.getStrippedList(excludedItems, this.specialDataset)
|
||||
else
|
||||
return this.specialDataset;
|
||||
}
|
||||
/**
|
||||
* Gets the list of INSA's services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItemType>}
|
||||
*/
|
||||
getINSAServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||
if (excludedItems != null)
|
||||
return getStrippedServicesList(excludedItems, this.insaDataset);
|
||||
return this.insaDataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all services sorted by category
|
||||
*
|
||||
* @param excludedItems Ids of categories to exclude from the returned list
|
||||
* @returns {Array<ServiceCategory>}
|
||||
*/
|
||||
getCategories(excludedItems?: Array<string>) {
|
||||
if (excludedItems != null)
|
||||
return this.getStrippedList(excludedItems, this.categoriesDataset)
|
||||
else
|
||||
return this.categoriesDataset;
|
||||
}
|
||||
/**
|
||||
* Gets the list of special services
|
||||
*
|
||||
* @param excludedItems Ids of items to exclude from the returned list
|
||||
* @returns {Array<ServiceItemType>}
|
||||
*/
|
||||
getSpecialServices(excludedItems?: Array<string>): Array<ServiceItemType> {
|
||||
if (excludedItems != null)
|
||||
return getStrippedServicesList(excludedItems, this.specialDataset);
|
||||
return this.specialDataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 MascotPopup from '../../components/Mascot/MascotPopup';
|
||||
import DashboardManager from '../../managers/DashboardManager';
|
||||
import type {ServiceItem} from '../../managers/ServicesManager';
|
||||
import type {ServiceItemType} from '../../managers/ServicesManager';
|
||||
import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
|
||||
// import DATA from "../dashboard_data.json";
|
||||
|
||||
|
@ -230,7 +230,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
|||
* @param content
|
||||
* @return {*}
|
||||
*/
|
||||
getDashboardRow(content: Array<ServiceItem | null>): React.Node {
|
||||
getDashboardRow(content: Array<ServiceItemType | null>): React.Node {
|
||||
return (
|
||||
// $FlowFixMe
|
||||
<FlatList
|
||||
|
@ -256,7 +256,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
|||
getDashboardRowRenderItem = ({
|
||||
item,
|
||||
}: {
|
||||
item: ServiceItem | null,
|
||||
item: ServiceItemType | null,
|
||||
}): React.Node => {
|
||||
if (item != null)
|
||||
return (
|
||||
|
|
|
@ -1,149 +1,162 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import type {cardList} from "../../components/Lists/CardList/CardList";
|
||||
import CardList from "../../components/Lists/CardList/CardList";
|
||||
import {Image, View} from "react-native";
|
||||
import {Avatar, Card, Divider, List, TouchableRipple, withTheme} from "react-native-paper";
|
||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||
import {Image, View} from 'react-native';
|
||||
import {
|
||||
Avatar,
|
||||
Card,
|
||||
Divider,
|
||||
List,
|
||||
TouchableRipple,
|
||||
withTheme,
|
||||
} from 'react-native-paper';
|
||||
import i18n from 'i18n-js';
|
||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||
import {StackNavigationProp} from "@react-navigation/stack";
|
||||
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 {StackNavigationProp} from '@react-navigation/stack';
|
||||
import CardList from '../../components/Lists/CardList/CardList';
|
||||
import type {CustomTheme} from '../../managers/ThemeManager';
|
||||
import MaterialHeaderButtons, {
|
||||
Item,
|
||||
} from '../../components/Overrides/CustomHeaderButton';
|
||||
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 = {
|
||||
navigation: StackNavigationProp,
|
||||
theme: CustomTheme,
|
||||
}
|
||||
type PropsType = {
|
||||
navigation: StackNavigationProp,
|
||||
theme: CustomTheme,
|
||||
};
|
||||
|
||||
export type listItem = {
|
||||
title: string,
|
||||
description: string,
|
||||
image: string | number,
|
||||
content: cardList,
|
||||
}
|
||||
class ServicesScreen extends React.Component<PropsType> {
|
||||
finalDataset: Array<ServiceCategoryType>;
|
||||
|
||||
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) {
|
||||
super(props);
|
||||
const services = new ServicesManager(props.navigation);
|
||||
this.finalDataset = services.getCategories([SERVICES_CATEGORIES_KEY.SPECIAL])
|
||||
}
|
||||
onAboutPress = () => {
|
||||
const {props} = this;
|
||||
props.navigation.navigate('amicale-contact');
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.navigation.setOptions({
|
||||
headerRight: this.getAboutButton,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets the list title image for the list.
|
||||
*
|
||||
* 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>
|
||||
<Item title="information" iconName="information" onPress={this.onAboutPress}/>
|
||||
</MaterialHeaderButtons>;
|
||||
/**
|
||||
* A list item showing a list of available services for the current category
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Gets the list title image for the list.
|
||||
*
|
||||
* If the source is a string, we are using an icon.
|
||||
* If the source is a number, we are using an internal image.
|
||||
*
|
||||
* @param props Props to pass to the component
|
||||
* @param source The source image to display. Can be a string for icons or a number for local images
|
||||
* @returns {*}
|
||||
*/
|
||||
getListTitleImage(props, source: string | number) {
|
||||
if (typeof source === "number")
|
||||
return <Image
|
||||
size={48}
|
||||
source={source}
|
||||
style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
}}/>
|
||||
else
|
||||
return <Avatar.Icon
|
||||
{...props}
|
||||
size={48}
|
||||
icon={source}
|
||||
color={this.props.theme.colors.primary}
|
||||
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>
|
||||
);
|
||||
}
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<CollapsibleFlatList
|
||||
data={this.finalDataset}
|
||||
renderItem={this.getRenderItem}
|
||||
keyExtractor={this.keyExtractor}
|
||||
ItemSeparatorComponent={(): React.Node => <Divider />}
|
||||
hasTab
|
||||
/>
|
||||
<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',
|
||||
},
|
||||
}}
|
||||
emotion={MASCOT_STYLE.WINK}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(ServicesScreen);
|
||||
|
|
|
@ -1,58 +1,65 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import CardList from "../../components/Lists/CardList/CardList";
|
||||
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||
import {withCollapsible} from "../../utils/withCollapsible";
|
||||
import {Collapsible} from "react-navigation-collapsible";
|
||||
import {CommonActions} from "@react-navigation/native";
|
||||
import type {listItem} from "./ServicesScreen";
|
||||
import {StackNavigationProp} from "@react-navigation/stack";
|
||||
import {Collapsible} from 'react-navigation-collapsible';
|
||||
import {CommonActions} from '@react-navigation/native';
|
||||
import {StackNavigationProp} from '@react-navigation/stack';
|
||||
import CardList from '../../components/Lists/CardList/CardList';
|
||||
import CustomTabBar from '../../components/Tabbar/CustomTabBar';
|
||||
import {withCollapsible} from '../../utils/withCollapsible';
|
||||
import type {ServiceCategoryType} from '../../managers/ServicesManager';
|
||||
|
||||
type Props = {
|
||||
navigation: StackNavigationProp,
|
||||
route: { params: { data: listItem | null } },
|
||||
collapsibleStack: Collapsible,
|
||||
}
|
||||
type PropsType = {
|
||||
navigation: StackNavigationProp,
|
||||
route: {params: {data: ServiceCategoryType | null}},
|
||||
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);
|
||||
this.handleNavigationParams();
|
||||
/**
|
||||
* Recover the list to display from navigation parameters
|
||||
*/
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover the list to display from navigation parameters
|
||||
*/
|
||||
handleNavigationParams() {
|
||||
if (this.props.route.params != null) {
|
||||
if (this.props.route.params.data != null) {
|
||||
this.finalDataset = this.props.route.params.data;
|
||||
// reset params to prevent infinite loop
|
||||
this.props.navigation.dispatch(CommonActions.setParams({data: null}));
|
||||
this.props.navigation.setOptions({
|
||||
headerTitle: this.finalDataset.title,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
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}}
|
||||
/>
|
||||
}
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
const {
|
||||
containerPaddingTop,
|
||||
scrollIndicatorInsetTop,
|
||||
onScroll,
|
||||
} = 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);
|
||||
|
|
19
src/utils/Services.js
Normaal bestaand
19
src/utils/Services.js
Normaal bestaand
|
@ -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;
|
||||
}
|
Laden…
Reference in a new issue