Improved website handling

This commit is contained in:
Arnaud Vergnet 2020-07-01 20:01:14 +02:00
parent b813aa0b83
commit d622a2f77a
17 changed files with 155 additions and 276 deletions

View file

@ -0,0 +1,13 @@
export default {
websites: {
AMICALE: "https://www.amicale-insat.fr/",
AVAILABLE_ROOMS: "http://planex.insa-toulouse.fr/salles.php",
BIB: "https://bibbox.insa-toulouse.fr/",
BLUEMIND: "https://etud-mel.insa-toulouse.fr/webmail/",
ELUS_ETUDIANTS: "https://etud.insa-toulouse.fr/~eeinsat/",
ENT: "https://ent.insa-toulouse.fr/",
INSA_ACCOUNT: "https://moncompte.insa-toulouse.fr/",
TUTOR_INSA: "https://www.etud.insa-toulouse.fr/~tutorinsa/",
WIKETUD: "https://wiki.etud.insa-toulouse.fr/",
},
}

View file

@ -12,24 +12,17 @@ import TetrisScreen from "../screens/Tetris/TetrisScreen";
import VoteScreen from "../screens/Amicale/VoteScreen";
import LoginScreen from "../screens/Amicale/LoginScreen";
import {Platform} from "react-native";
import AvailableRoomScreen from "../screens/Services/Websites/AvailableRoomScreen";
import BibScreen from "../screens/Services/Websites/BibScreen";
import SelfMenuScreen from "../screens/Services/SelfMenuScreen";
import ProximoMainScreen from "../screens/Services/Proximo/ProximoMainScreen";
import ProximoListScreen from "../screens/Services/Proximo/ProximoListScreen";
import ProximoAboutScreen from "../screens/Services/Proximo/ProximoAboutScreen";
import {AmicaleWebsiteScreen} from "../screens/Services/Websites/AmicaleWebsiteScreen";
import {ElusEtudiantsWebsiteScreen} from "../screens/Services/Websites/ElusEtudiantsWebsiteScreen";
import {WiketudWebsiteScreen} from "../screens/Services/Websites/WiketudWebsiteScreen";
import {TutorInsaWebsiteScreen} from "../screens/Services/Websites/TutorInsaWebsiteScreen";
import {ENTWebsiteScreen} from "../screens/Services/Websites/ENTWebsiteScreen";
import {BlueMindWebsiteScreen} from "../screens/Services/Websites/BlueMindWebsiteScreen";
import ProfileScreen from "../screens/Amicale/ProfileScreen";
import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen";
import ClubAboutScreen from "../screens/Amicale/Clubs/ClubAboutScreen";
import ClubDisplayScreen from "../screens/Amicale/Clubs/ClubDisplayScreen";
import {createScreenCollapsibleStack, getWebsiteStack} from "../utils/CollapsibleUtils";
import BugReportScreen from "../screens/Other/FeedbackScreen";
import WebsiteScreen from "../screens/Services/WebsiteScreen";
const modalTransition = Platform.OS === 'ios' ? TransitionPresets.ModalPresentationIOS : TransitionPresets.ModalSlideFromBottomIOS;
@ -102,12 +95,10 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
}}
/>
{/* INSA */}
{getWebsiteStack("available-rooms", MainStack, AvailableRoomScreen, i18n.t('screens.availableRooms'))}
{getWebsiteStack("bib", MainStack, BibScreen, i18n.t('screens.bib'))}
{createScreenCollapsibleStack("self-menu", MainStack, SelfMenuScreen, i18n.t('screens.menuSelf'))}
{getWebsiteStack("website", MainStack, WebsiteScreen, "")}
{/* STUDENTS */}
{createScreenCollapsibleStack("self-menu", MainStack, SelfMenuScreen, i18n.t('screens.menuSelf'))}
{createScreenCollapsibleStack("proximo", MainStack, ProximoMainScreen, i18n.t('screens.proximo'))}
{createScreenCollapsibleStack(
"proximo-list",
@ -125,15 +116,7 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
...modalTransition,
}}
/>
{getWebsiteStack("amicale-website", MainStack, AmicaleWebsiteScreen, i18n.t('screens.amicaleWebsite'))}
{getWebsiteStack("elus-etudiants", MainStack, ElusEtudiantsWebsiteScreen, "Élus Étudiants")}
{getWebsiteStack("wiketud", MainStack, WiketudWebsiteScreen, "Wiketud")}
{getWebsiteStack("tutorinsa", MainStack, TutorInsaWebsiteScreen, "Tutor'INSA")}
{getWebsiteStack("ent", MainStack, ENTWebsiteScreen, i18n.t('screens.ent'))}
{getWebsiteStack("bluemind", MainStack, BlueMindWebsiteScreen, i18n.t('screens.bluemind'))}
{/* AMICALE */}
{createScreenCollapsibleStack("profile", MainStack, ProfileScreen, i18n.t('screens.profile'))}
{createScreenCollapsibleStack("club-list", MainStack, ClubListScreen, i18n.t('clubs.clubList'))}
<MainStack.Screen

View file

@ -12,6 +12,7 @@ import CustomTabBar from "../../components/Tabbar/CustomTabBar";
import type {CustomTheme} from "../../managers/ThemeManager";
import AsyncStorageManager from "../../managers/AsyncStorageManager";
import {StackNavigationProp} from "@react-navigation/stack";
import AvailableWebsites from "../../constants/AvailableWebsites";
type Props = {
navigation: StackNavigationProp,
@ -110,7 +111,7 @@ class LoginScreen extends React.Component<Props, State> {
/**
* Navigates to the Amicale website screen with the reset password link as navigation parameters
*/
onResetPasswordClick = () => this.props.navigation.navigate('amicale-website', {path: RESET_PASSWORD_PATH});
onResetPasswordClick = () => this.props.navigation.navigate("website", {host: AvailableWebsites.websites.AMICALE, path: RESET_PASSWORD_PATH, title: i18n.t('screens.amicaleWebsite')});
/**
* The user has unfocused the input, his email is ready to be validated

View file

@ -14,6 +14,7 @@ import type {cardList} from "../../components/Lists/CardList/CardList";
import CardList from "../../components/Lists/CardList/CardList";
import {StackNavigationProp} from "@react-navigation/stack";
import type {CustomTheme} from "../../managers/ThemeManager";
import AvailableWebsites from "../../constants/AvailableWebsites";
type Props = {
navigation: StackNavigationProp,
@ -83,7 +84,7 @@ class ProfileScreen extends React.Component<Props, State> {
title: i18n.t('screens.amicaleWebsite'),
subtitle: i18n.t('servicesScreen.descriptions.amicaleWebsite'),
image: ICON_AMICALE,
onPress: () => this.props.navigation.navigate("amicale-website"),
onPress: () => this.props.navigation.navigate("website", {host: AvailableWebsites.websites.AMICALE, title: i18n.t('screens.amicaleWebsite')}),
},
];
}
@ -287,7 +288,7 @@ class ProfileScreen extends React.Component<Props, State> {
<Button
icon="account-edit"
mode="contained"
onPress={() => this.props.navigation.navigate('amicale-website', {path: this.data.link})}
onPress={() => this.props.navigation.navigate("website", {host: AvailableWebsites.websites.AMICALE, path: this.data.link, title: i18n.t('screens.amicaleWebsite')})}
style={styles.editButton}>
{i18n.t("profileScreen.editInformation")}
</Button>

View file

@ -22,6 +22,7 @@ import LogoutDialog from "../../components/Amicale/LogoutDialog";
import {withCollapsible} from "../../utils/withCollapsible";
import {Collapsible} from "react-navigation-collapsible";
import AsyncStorageManager from "../../managers/AsyncStorageManager";
import AvailableWebsites from "../../constants/AvailableWebsites";
// import DATA from "../dashboard_data.json";
@ -217,7 +218,7 @@ class HomeScreen extends React.Component<Props, State> {
};
onTutorInsaClick = () => {
this.props.navigation.navigate("tutorinsa");
this.props.navigation.navigate("website", {host: AvailableWebsites.websites.TUTOR_INSA, title: "Tutor'INSA"});
};
onMenuClick = () => {

View file

@ -13,6 +13,7 @@ import i18n from 'i18n-js';
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
import ConnectionManager from "../../managers/ConnectionManager";
import {StackNavigationProp} from "@react-navigation/stack";
import AvailableWebsites from "../../constants/AvailableWebsites";
type Props = {
navigation: StackNavigationProp,
@ -43,6 +44,7 @@ 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";
class ServicesScreen extends React.Component<Props> {
@ -72,7 +74,7 @@ class ServicesScreen extends React.Component<Props> {
title: i18n.t('screens.amicaleWebsite'),
subtitle: i18n.t('servicesScreen.descriptions.amicaleWebsite'),
image: AMICALE_IMAGE,
onPress: () => nav.navigate("amicale-website"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.AMICALE, title: i18n.t('screens.amicaleWebsite')}),
},
{
title: i18n.t('screens.vote'),
@ -92,19 +94,19 @@ class ServicesScreen extends React.Component<Props> {
title: "Wiketud",
subtitle: i18n.t('servicesScreen.descriptions.wiketud'),
image: WIKETUD_IMAGE,
onPress: () => nav.navigate("wiketud"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.WIKETUD, title: "Wiketud"}),
},
{
title: "Élus Étudiants",
subtitle: i18n.t('servicesScreen.descriptions.elusEtudiants'),
image: EE_IMAGE,
onPress: () => nav.navigate("elus-etudiants"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.ELUS_ETUDIANTS, title: "Élus Étudiants"}),
},
{
title: "Tutor'INSA",
subtitle: i18n.t('servicesScreen.descriptions.tutorInsa'),
image: TUTORINSA_IMAGE,
onPress: () => nav.navigate("tutorinsa"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.TUTOR_INSA, title: "Tutor'INSA"})
},
];
this.insaDataset = [
@ -118,25 +120,31 @@ class ServicesScreen extends React.Component<Props> {
title: i18n.t('screens.availableRooms'),
subtitle: i18n.t('servicesScreen.descriptions.availableRooms'),
image: ROOM_IMAGE,
onPress: () => nav.navigate("available-rooms"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.AVAILABLE_ROOMS, title: i18n.t('screens.availableRooms')}),
},
{
title: i18n.t('screens.bib'),
subtitle: i18n.t('servicesScreen.descriptions.bib'),
image: BIB_IMAGE,
onPress: () => nav.navigate("bib"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.BIB, title: i18n.t('screens.bib')}),
},
{
title: i18n.t('screens.bluemind'),
subtitle: i18n.t('servicesScreen.descriptions.mails'),
image: EMAIL_IMAGE,
onPress: () => nav.navigate("bluemind"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.BLUEMIND, title: i18n.t('screens.bluemind')}),
},
{
title: i18n.t('screens.ent'),
subtitle: i18n.t('servicesScreen.descriptions.ent'),
image: ENT_IMAGE,
onPress: () => nav.navigate("ent"),
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.ENT, title: i18n.t('screens.ent')}),
},
{
title: i18n.t('screens.insaAccount'),
subtitle: i18n.t('servicesScreen.descriptions.insaAccount'),
image: ACCOUNT_IMAGE,
onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.INSA_ACCOUNT, title: i18n.t('screens.insaAccount')}),
},
];
this.finalDataset = [

View file

@ -0,0 +1,109 @@
// @flow
import * as React from 'react';
import {StackNavigationProp} from "@react-navigation/stack";
import WebViewScreen from "../../components/Screens/WebViewScreen";
import AvailableWebsites from "../../constants/AvailableWebsites";
import BasicLoadingScreen from "../../components/Screens/BasicLoadingScreen";
type Props = {
navigation: StackNavigationProp,
route: { params: { host: string, path: string | null, title: string } },
}
class WebsiteScreen extends React.Component<Props> {
fullUrl: string;
injectedJS: { [key: string]: string };
customPaddingFunctions: {[key: string]: (padding: string) => string}
host: string;
constructor(props: Props) {
super(props);
this.props.navigation.addListener('focus', this.onScreenFocus);
this.injectedJS = {};
this.customPaddingFunctions = {};
this.injectedJS[AvailableWebsites.websites.AVAILABLE_ROOMS] =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<style>body,body>.container2{padding-top:0;width:100%}b,body>.container2>h1,body>.container2>h3,br,header{display:none}.table-bordered td,.table-bordered th{border:none;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.table{padding:0;margin:0;width:200%;max-width:200%;display:block}tbody{display:block;width:100%}thead{display:block;width:100%}.table tbody tr,tbody tr[bgcolor],thead tr{width:100%;display:inline-flex}.table tbody td,.table thead td[colspan]{padding:0;flex:1;height:50px;margin:0}.table tbody td[bgcolor=white],.table thead td,.table>tbody>tr>td:nth-child(1){flex:0 0 150px;height:50px}</style>\'; true;';
this.injectedJS[AvailableWebsites.websites.BIB] =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<style>.hero-unit,.navbar,footer{display:none}.hero-unit-form,.hero-unit2,.hero-unit3{background-color:#fff;box-shadow:none;padding:0;margin:0}.hero-unit-form h4{font-size:2rem;line-height:2rem}.btn{font-size:1.5rem;line-height:1.5rem;padding:20px}.btn-danger{background-image:none;background-color:#be1522}.table{font-size:.8rem}.table td{padding:0;height:18.2333px;border:none;border-bottom:1px solid #c1c1c1}.table td[style="max-width:55px;"]{max-width:110px!important}.table-bordered{min-width:50px}th{height:50px}.table-bordered{border-collapse:collapse}</style>\';' +
'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
'$(".hero-unit-form").append("' +
'<div style=\'width: 100%; display: flex\'>' +
'<a style=\'margin: auto\' href=\'' + AvailableWebsites.websites.BIB + '\'>' +
'<button id=\'customBackButton\' class=\'btn btn-primary\'>Retour</button>' +
'</a>' +
'</div>");true;';
this.customPaddingFunctions[AvailableWebsites.websites.BLUEMIND] = (padding: string) => {
return (
"$('head').append('<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">');" +
"$('.minwidth').css('top', " + padding + ");" +
"$('#mailview-bottom').css('min-height', 500);"
);
};
this.customPaddingFunctions[AvailableWebsites.websites.WIKETUD] = (padding: string) => {
return (
"$('#p-logo-text').css('top', 10 + " + padding + ");" +
"$('#site-navigation h2').css('top', 10 + " + padding + ");" +
"$('#site-tools h2').css('top', 10 + " + padding + ");" +
"$('#user-tools h2').css('top', 10 + " + padding + ");"
);
}
}
onScreenFocus = () => {
this.handleNavigationParams();
};
/**
*
*/
handleNavigationParams() {
if (this.props.route.params != null) {
this.host = this.props.route.params.host;
let path = this.props.route.params.path;
const title = this.props.route.params.title;
if (this.host != null && path != null) {
path = path.replace(this.host, "");
this.fullUrl = this.host + path;
}else
this.fullUrl = this.host;
if (title != null)
this.props.navigation.setOptions({title: title});
}
}
render() {
let injectedJavascript = "";
let customPadding = null;
if (this.host != null && this.injectedJS[this.host] != null)
injectedJavascript = this.injectedJS[this.host];
if (this.host != null && this.customPaddingFunctions[this.host] != null)
customPadding = this.customPaddingFunctions[this.host];
if (this.fullUrl != null) {
return (
<WebViewScreen
{...this.props}
url={this.fullUrl}
customJS={injectedJavascript}
customPaddingFunction={customPadding}
/>
);
} else {
return (
<BasicLoadingScreen/>
);
}
}
}
export default WebsiteScreen;

View file

@ -1,25 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://www.amicale-insat.fr/';
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const AmicaleWebsiteScreen = (props: Object) => {
let path = '';
if (props.route.params !== undefined) {
if (props.route.params.path !== undefined && props.route.params.path !== null) {
path = props.route.params.path;
path = path.replace(URL, '');
}
}
return (
<WebViewScreen
{...props}
url={URL + path}/>
);
};

View file

@ -1,45 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
type Props = {
navigation: Object,
}
const ROOM_URL = 'http://planex.insa-toulouse.fr/salles.php';
const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile2.css';
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export default class AvailableRoomScreen extends React.Component<Props> {
customInjectedJS: string;
/**
* Defines custom injected JavaScript to improve the page display on mobile
*/
constructor() {
super();
this.customInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';' +
'let header = $(".table tbody tr:first");' +
'$("table").prepend("<thead></thead>");true;' + // Fix for crash on ios
'$("thead").append(header);true;';
}
render() {
const nav = this.props.navigation;
return (
<WebViewScreen
navigation={nav}
url={ROOM_URL}
customJS={this.customInjectedJS}/>
);
}
}

View file

@ -1,57 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
type Props = {
navigation: Object,
}
const BIB_URL = 'https://bibbox.insa-toulouse.fr/';
const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile.css';
const CUSTOM_CSS_Bib = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customBibMobile.css';
/**
* Class defining the app's Bib screen.
* This screen uses a webview to render the page
*/
export default class AvailableRoomScreen extends React.Component<Props> {
customInjectedJS: string;
customBibInjectedJS: string;
/**
* Defines custom injected JavaScript to improve the page display on mobile
*/
constructor() {
super();
this.customInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';' +
'let header = $(".table tbody tr:first");' +
'$("table").prepend("<thead></thead>");true;' + // Fix for crash on ios
'$("thead").append(header);true;';
this.customBibInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_Bib + '" type="text/css"/>\';' +
'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
'$(".hero-unit-form").append("' +
'<div style=\'width: 100%; display: flex\'>' +
'<a style=\'margin: auto\' href=\'' + BIB_URL + '\'>' +
'<button id=\'customBackButton\' class=\'btn btn-primary\'>Retour</button>' +
'</a>' +
'</div>");true;';
}
render() {
const nav = this.props.navigation;
return (
<WebViewScreen
navigation={nav}
url={BIB_URL}
customJS={this.customBibInjectedJS}/>
);
}
}

View file

@ -1,28 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://etud-mel.insa-toulouse.fr/webmail/';
const customPadding = (padding: string) => {
return (
"$('head').append('<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">');" +
"$('.minwidth').css('top', " + padding + ");" +
"$('#mailview-bottom').css('min-height', 500);"
);
}
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const BlueMindWebsiteScreen = (props: Object) => {
return (
<WebViewScreen
{...props}
customPaddingFunction={customPadding}
url={URL}/>
);
};

View file

@ -1,18 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://ent.insa-toulouse.fr/';
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const ENTWebsiteScreen = (props: Object) => {
return (
<WebViewScreen
{...props}
url={URL}/>
);
};

View file

@ -1,18 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://etud.insa-toulouse.fr/~eeinsat/';
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const ElusEtudiantsWebsiteScreen = (props: Object) => {
return (
<WebViewScreen
{...props}
url={URL}/>
);
};

View file

@ -1,18 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://www.etud.insa-toulouse.fr/~tutorinsa/';
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const TutorInsaWebsiteScreen = (props: Object) => {
return (
<WebViewScreen
{...props}
url={URL}/>
);
};

View file

@ -1,30 +0,0 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../../components/Screens/WebViewScreen";
const URL = 'https://wiki.etud.insa-toulouse.fr/';
const customPadding = (padding: string) => {
return (
"$('#p-logo-text').css('top', 10 + " + padding + ");" +
"$('#site-navigation h2').css('top', 10 + " + padding + ");" +
"$('#site-tools h2').css('top', 10 + " + padding + ");" +
"$('#user-tools h2').css('top', 10 + " + padding + ");"
);
}
/**
* Class defining the app's available rooms screen.
* This screen uses a webview to render the page
*/
export const WiketudWebsiteScreen = (props: Object) => {
return (
<WebViewScreen
{...props}
customPaddingFunction={customPadding}
url={URL}/>
);
};

View file

@ -26,7 +26,7 @@
"vote": "Elections",
"scanner": "Scanotron 3000",
"feedback": "Feedback",
"map": "Campus Map"
"insaAccount": "INSA Account"
},
"intro": {
"slideMain": {
@ -427,7 +427,8 @@
"availableRooms": "See how many rooms are free",
"bib": "Book a Bib'Box for project work",
"mails": "Check your INSA mails",
"ent": "See your grades"
"ent": "See your grades",
"insaAccount": "See your information and change your password"
}
},
"planningScreen": {

View file

@ -26,7 +26,7 @@
"vote": "Élections",
"scanner": "Scanotron 3000",
"feedback": "Votre avis",
"map": "Carte du campus"
"insaAccount": "Compte INSA"
},
"intro": {
"slideMain": {
@ -429,7 +429,8 @@
"availableRooms": "Vérifiez les salles disponibles",
"bib": "Réservez une Bib'Box pour les travaux de groupe",
"mails": "Vérifiez vos mails INSA",
"ent": "Retrouvez vos notes"
"ent": "Retrouvez vos notes",
"insaAccount": "Accédez à vos informations et modifiez votre mot de passe"
}
},
"planningScreen": {