Technical Documentation - EPITECH-ESPEEN/ESPEEN-Frontend-mobile GitHub Wiki
Espeen is an action-reaction based system that allows users to define and automate interactions between different areas of functionality. Users set up specific actions, which trigger corresponding reactions within the system, making it a highly flexible solution for task automation, workflow management, and real-time event handling.
The Espeen project is built using the MERN stack:
- MongoDB for the database,
- Express for the backend framework,
- React for the front-end user interface, and
- Node.js as the runtime environment for the backend.
This document is specifically focused on the mobile app part of AREA, which is built using React Native. It will guide developers on how to set up, extend, and contribute to the mobile interface that interacts with the AREA system.
Other Documentation Links
To develop and contribute to the AREA mobile app, ensure your development environment meets the following requirements:
- Node.js: Version 14 or higher (recommended).
- Package Manager: npm or Yarn.
-
Expo CLI: Install Expo CLI globally using npm:
npm install -g expo-cli
The AREA mobile app is built using the following technologies:
- React Native: A framework for building native apps using React.
- TypeScript: A superset of JavaScript that adds static types, helping to catch errors early and improve code quality.
- i18next: A powerful internationalization framework that handles translations and language switching.
- React Navigation: A library for routing and navigation in React Native apps.
- React Native Paper: A library of UI components that follow Material Design guidelines.
This combination of technologies provides a robust and flexible environment for developing interactive mobile applications.
To contribute effectively, you should have:
- A basic understanding of JavaScript and TypeScript.
- Familiarity with React Native and its component-based architecture.
- Experience with navigation concepts, particularly React Navigation.
- Knowledge of CSS-in-JS styling techniques, especially in React Native.
-
Clone the Repository: Clone the repository to your local machine using:
git clone https://github.com/EPITECH-ESPEEN/ESPEEN-Front-End-Mobile.git
-
Navigate to the Project Directory:
cd ESPEEN-Front-End-Mobile
With these prerequisites in place, you will be ready to set up the project and begin contributing!
To set up the AREA mobile app on your local machine, follow these steps:
-
Clone the Repository: If you haven't done so already, clone the repository using:
git clone https://github.com/EPITECH-ESPEEN/ESPEEN-Front-End-Mobile.git
-
Navigate to the Project Directory:
cd ESPEEN-Front-End-Mobile
-
Install Dependencies: Use npm or Yarn to install the required dependencies:
- With npm:
npm install
- With Yarn:
yarn install
Once the dependencies are installed, you can start the development server and view the application on your mobile device:
-
Start the Server: Run the following command:
npm start
or, if using Yarn:
yarn start
-
Open Expo Go: Install the Expo Go app on your mobile device from the App Store or Google Play Store.
-
Enable Developer Mode and USB Debugging:
- For Android: Go to your device's settings, enable Developer options, and turn on USB Debugging.
- For iOS: Connect your device via USB and ensure you have the necessary permissions.
-
Scan the QR Code: Open Expo Go on your mobile device, select "Scan QR Code," and scan the QR code displayed in your terminal or browser to load the app.
ā ļø WARNING: Backend Running
For a fully functional application, ensure that the backend is running as well. The backend is essential for handling authentication and other server-side processes. You can find the backend setup instructions in the Backend Documentation.
To create an optimized build of the application for deployment, follow these steps:
-
Run the Build Command: Execute the following command:
npm run build
or, if using Yarn:
yarn build
-
Locate the Build Files: After the build process completes, the optimized files will be located in the
build
directory, ready for deployment.
With these setup instructions, you should be ready to develop and contribute to the AREA mobile app!
The AREA mobile app follows a well-organized folder structure that facilitates easy navigation and understanding of the codebase. Below is an overview of the key directories and their purposes.
-
assets
:-
fonts
: Contains font files used in the application, including variations of Montserrat. -
img
: Stores images used in the application (e.g., icons and splash images).
-
-
bin
: Contains scripts for various utilities, such as the i18n translation script and installation scripts. -
components
: Contains reusable React components organized into subdirectories based on functionality (e.g., forms, inputs, loading states, etc.). -
eas.json
: Configuration file for EAS (Expo Application Services). -
i18n
: Holds internationalization files for handling translations, including language files and the main i18n configuration. -
router
: Configuration for application routing. -
screens
: Contains screen components for different app views, such as login, profile, and area screens. -
services
: Utility services for API calls and business logic, including authentication and fetching data. -
stores
: Contains state management files for managing global application state. -
styles
: Global stylesheets and configuration for application styling. -
types
: TypeScript type definitions used throughout the application. -
Root Files: Includes essential project files such as
package.json
, configuration files (e.g.,tsconfig.json
), and theApp.tsx
as the main application entry point.
- Use camelCase for component files and folder names (e.g.,
loginForm.tsx
). - Organize components and related styles in the same directory whenever possible to maintain clarity.
By following this structure and naming convention, contributors can ensure consistency and maintainability throughout the project.
When creating a new component in the AREA mobile app, follow the established structure and conventions to ensure consistency and clarity. A classic mobile component should be organized as follows:
/*
Author:
>> Nathan TIROLF - { nathan.tirolf@epitech.eu }
(āā¢ Ö ā¢ā)ā¤
āāUāāāUāāāāāāāāāāāāāā
ā Have a good day ! ā
āāāāāāāāāāāāāāāāāāāāā
*/
/* ----- IMPORTS ----- */
import React from "react";
import { Button as PaperButton } from "react-native-paper";
import { StyleSheet } from "react-native";
import { colors } from "../../styles/colors";
/* ----- PROPS ----- */
interface ButtonProps {
label: string;
onPress: () => void;
}
/* ----- COMPONENT ----- */
const Button: React.FC<ButtonProps> = ({ label, onPress }) => {
return (
<PaperButton
mode="text"
onPress={onPress}
contentStyle={styles.buttonContent}
style={styles.container}
labelStyle={styles.label}
>
{label}
</PaperButton>
);
};
/* ----- STYLES ----- */
const styles = StyleSheet.create({
container: {
borderRadius: 10,
borderWidth: 4,
borderColor: colors.light,
justifyContent: "center",
},
buttonContent: {
padding: 8,
paddingLeft: 16,
paddingRight: 16,
},
label: {
fontFamily: "montserrat-alternates-bold",
color: colors.light,
fontSize: 18,
},
});
export default Button;
-
Header:
- Include a header comment at the top of the file. List the author and their email for easy identification and communication.
- A friendly message can be added for a personal touch.
- So copy and paste the header when you create a new file (change/add your name and email).
-
Imports:
- Group all imports together.
- Use a comment (
/* ----- IMPORTS ----- */
) to indicate this section clearly.
-
Props:
- Define the component's props using TypeScript interfaces. This ensures type safety and better documentation for other developers.
- Use a comment (
/* ----- PROPS ----- */
) to denote this section.
-
Component:
- Define the functional component with a clear and descriptive name, using PascalCase for the component name.
- Implement the component logic following the props definition.
- Use comments to describe key parts of the logic, making it easier for others to understand.
-
Styles:
- Define styles using
StyleSheet.create()
from React Native, and include a section for styles clearly marked with a comment (/* ----- STYLES ----- */
).
- Define styles using
-
Exporting the Component:
- Always export the component at the end of the file to make it available for import in other parts of the application.
- Ensure that your component adheres to the established folder structure and naming conventions.
- Maintain clarity with comments throughout the code, especially in complex logic, to enhance readability and maintainability.
- Aim for a clean and consistent style, which will make collaboration and onboarding easier for new developers.
In the AREA mobile app, screens are managed through a centralized configuration file located at src/router/routerConfig.ts
. To create and configure a new screen, follow these steps:
-
Locate the Router Configuration: Open the
routerConfig.ts
file to access the existing screen configurations./* Author: >> Nathan TIROLF - { nathan.tirolf@epitech.eu } (āā¢ Ö ā¢ā)⤠āāUāāāUāāāāāāāāāāāāāā ā Have a good day ! ā āāāāāāāāāāāāāāāāāāāāā */ import { Library, UserRound, Waypoints } from "lucide-react-native"; import EspeenIcon from "../components/icons/espeenIcon"; import EspeenScreen from "../screens/espeenScreen"; import ServicesScreen from "../screens/servicesScreen"; import AreaScreen from "../screens/areaScreen"; import ProfileScreen from "../screens/profileScreen"; import LoginScreen from "../screens/loginScreen"; export type ScreenConfig = { name: string; content: React.FC; icon?: React.FC; logged: boolean; accessible: boolean; subScreen?: string; } const ScreensConfigs: ScreenConfig[] = [ { name: 'Espeen', content: EspeenScreen, icon: EspeenIcon, logged: false, accessible: true }, { name: 'services', content: ServicesScreen, icon: Library, logged: true, accessible: true }, { name: 'AREA', content: AreaScreen, icon: Waypoints, logged: true, accessible: true }, { name: 'profile', content: ProfileScreen, icon: UserRound, logged: true, accessible: true }, { name: 'login', content: LoginScreen, logged: false, accessible: false }, ] export function getScreensConfigs(): ScreenConfig[] { return ScreensConfigs; } export function getScreenConfig(name: string): ScreenConfig | undefined { return ScreensConfigs.find(screen => screen.name === name); }
-
Adding a New Screen: To add a new screen, simply append it to the
ScreensConfigs
array, ensuring that it adheres to theScreenConfig
type:export type ScreenConfig = { name: string; content: React.FC; icon?: React.FC; logged: boolean; accessible: boolean; subScreen?: string; }
-
name: The name of the screen. If the first letter is uppercase, the i18n translation will be disabled, and the name will be used directly (e.g., "Espeen" does not require translation). For names that need translation, format the name as
dico.${name}
and ensure it is added to the i18n translation files.- See below for details on how to contribute and use the i18n automation.
-
content: The component that represents the screen. Each screen component should be located in the
screens/{name}Screen.tsx
file and follow the specific structure without needing a separate content component. - icon: An optional React component that represents the icon for the screen in the navigation bar.
- logged: A boolean indicating whether the user must be authenticated to access the screen.
- accessible: A boolean indicating if the screen is accessible from the navigation bar.
- subScreen: An optional string that indicates if the screen is a sub-screen of another.
-
name: The name of the screen. If the first letter is uppercase, the i18n translation will be disabled, and the name will be used directly (e.g., "Espeen" does not require translation). For names that need translation, format the name as
For managing internationalization (i18n) in the AREA project, we have an automation script located at bin/i18nTranslation
. This script is designed to update and generate i18n translations, and it uses gb-translation.json
as the base for all translations.
-
Base Translation File: The
gb-translation.json
file serves as the authoritative source for all translation keys. Any new keys or updates should be made in this file. -
Adding a New Translation Language: To add a new translation language, run the script with the following command:
./bin/i18nTranslation {Lang Code} {Lang Name}
For example, to add the Chinese language, use:
./bin/i18nTranslation CN China
-
Important: The script uses the language code to retrieve the corresponding flag from an API (e.g.,
https://flagsapi.com/CN/flat/64.png
). Ensure that the flag exists before adding a new language to avoid any issues.
-
Important: The script uses the language code to retrieve the corresponding flag from an API (e.g.,
-
Updating All Existing Translations: To update all existing translations without adding a new language, simply run the script without any arguments:
./bin/i18nTranslation
- In all cases, the script relies on the
gb-translation.json
file as the only true source for translations. Ensure this file is always up-to-date with the necessary translation keys before running the script.
We use a structured process for contributing to the project, which includes creating branches, making commits, and using GitHub issues for tracking tasks.
- Always create a new branch from
main
for any feature, bug fix, or other changes. - Make the branch name as explicit as possible to describe the purpose of the work.
- Once your work is complete, create a pull request. A lead developer will review it before it can be merged into
main
.
Follow this format for your commits:
[{type}] {summary}
{details}
Where:
-
Type indicates the nature of the commit:
-
+
for additions -
-
for deletions -
~
for updates or fixes
-
- Summary provides a brief description of the change.
- Details (optional) offers further explanation of the commit if necessary.
We track features and fixes using GitHub issues. Before starting on a task, check the issue board to see if the task is already defined. Always reference relevant issues in your pull requests and commit messages to provide context for your changes.
To handle authentication and user management we use redux.
- Datas are stored in
redux.state.auth.user
- You can use
useSelector()
to get thestate.auth
- If you just need to check if the user is authenticated without getting all the informations, you can use
redux.state.isAuthenticated
const { isAuthenticated } = useSelector((state) => state.auth);
- Official documentation
- We use
persist-redux
to keep the user connected. - To completely logout the user, you need to
persist.purge()
to remove the connected user from the persistence.