diff --git a/.expo/README.md b/.expo/README.md
new file mode 100644
index 0000000..fd146b4
--- /dev/null
+++ b/.expo/README.md
@@ -0,0 +1,15 @@
+> Why do I have a folder named ".expo" in my project?
+
+The ".expo" folder is created when an Expo project is started using "expo start" command.
+
+> What do the files contain?
+
+- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
+- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
+- "settings.json": contains the server configuration that is used to serve the application manifest.
+
+> Should I commit the ".expo" folder?
+
+No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
+
+Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
diff --git a/.expo/settings.json b/.expo/settings.json
new file mode 100644
index 0000000..92bc513
--- /dev/null
+++ b/.expo/settings.json
@@ -0,0 +1,8 @@
+{
+ "hostType": "lan",
+ "lanType": "ip",
+ "dev": true,
+ "minify": false,
+ "urlRandomness": null,
+ "https": false
+}
diff --git a/front/API.ts b/front/API.ts
index 1e3a92f..90b6b11 100644
--- a/front/API.ts
+++ b/front/API.ts
@@ -19,7 +19,7 @@ export default class API {
return {
name: "User",
email: "user@chromacase.com",
- xp: 0,
+ xp: 2345,
premium: false,
metrics: {},
settings: {},
diff --git a/front/App.tsx b/front/App.tsx
index 4cca4bf..46a8bd2 100644
--- a/front/App.tsx
+++ b/front/App.tsx
@@ -1,3 +1,4 @@
+import { NativeBaseProvider } from "native-base";
import Theme from './Theme';
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
@@ -5,7 +6,6 @@ import { Provider } from 'react-redux';
import store from './state/Store';
import { Router } from './Navigation';
import './i18n/i18n';
-import { NativeBaseProvider } from "native-base";
const queryClient = new QueryClient();
diff --git a/front/Navigation.tsx b/front/Navigation.tsx
index ff04104..466cfaa 100644
--- a/front/Navigation.tsx
+++ b/front/Navigation.tsx
@@ -10,7 +10,7 @@ import { translate } from './i18n/i18n';
const Stack = createNativeStackNavigator();
export const protectedRoutes = <>
-
+
>;
diff --git a/front/Theme.tsx b/front/Theme.tsx
index 62725e9..5baa003 100644
--- a/front/Theme.tsx
+++ b/front/Theme.tsx
@@ -4,7 +4,6 @@ import { extendTheme } from 'native-base';
* Using the Material Color guidelines
*/
const Theme = extendTheme({
- roundness: 10,
colors: {
primary:
{
@@ -45,7 +44,7 @@ const Theme = extendTheme({
800: '#262626',
900: '#0d0d0d',
},
- accent:
+ secondary:
{
50: '#d8ffff',
100: '#acffff',
diff --git a/front/components/Card.tsx b/front/components/Card.tsx
new file mode 100644
index 0000000..4ae34b6
--- /dev/null
+++ b/front/components/Card.tsx
@@ -0,0 +1,19 @@
+import { useTheme, Box } from 'native-base';
+import React from 'react';
+
+export const CardBorderRadius = 10;
+
+const cardBorder = (theme: ReturnType) => ({
+ borderColor: theme.colors.text[100],
+ borderRadius: CardBorderRadius,
+ borderWidth: 1
+})
+
+const Card = (props: any) => {
+ const theme = useTheme();
+ return
+ { props.children }
+
+}
+
+export default Card;
\ No newline at end of file
diff --git a/front/components/CompetenciesTable.tsx b/front/components/CompetenciesTable.tsx
new file mode 100644
index 0000000..628d346
--- /dev/null
+++ b/front/components/CompetenciesTable.tsx
@@ -0,0 +1,38 @@
+import { useNavigation } from "@react-navigation/core";
+import { HStack, VStack, Text, Progress, Pressable } from "native-base";
+import { translate } from "../i18n/i18n";
+import Card from './Card';
+
+type CompetenciesTableProps = {
+ pedalsCompetency: number;
+ rightHandCompetency: number;
+ leftHandCompetency: number;
+ accuracyCompetency: number;
+ arpegeCompetency: number;
+ chordsCompetency: number;
+}
+
+const CompetenciesTable = (props: CompetenciesTableProps) => {
+ const navigation = useNavigation();
+ return navigation.navigate('User')}>
+ {({ isHovered, isFocused }) => (
+
+
+
+ { Object.keys(props).map((competencyName) => (
+ {translate(competencyName as keyof CompetenciesTableProps)}
+ ))}
+
+
+ { Object.keys(props).map((competencyName) => (
+
+ ))}
+
+
+
+
+ )}
+
+}
+
+export default CompetenciesTable
\ No newline at end of file
diff --git a/front/components/loading.tsx b/front/components/Loading.tsx
similarity index 84%
rename from front/components/loading.tsx
rename to front/components/Loading.tsx
index 019c4bb..e46a71c 100644
--- a/front/components/loading.tsx
+++ b/front/components/Loading.tsx
@@ -3,4 +3,6 @@ import { Spinner } from "native-base";
const LoadingComponent = () => {
const theme = useTheme();
return
-}
\ No newline at end of file
+}
+
+export default LoadingComponent;
\ No newline at end of file
diff --git a/front/components/SongCard.tsx b/front/components/SongCard.tsx
new file mode 100644
index 0000000..98bc10a
--- /dev/null
+++ b/front/components/SongCard.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import Card, { CardBorderRadius } from './Card';
+import { VStack, Text, Image, Pressable } from 'native-base';
+import { useNavigation } from "@react-navigation/core";
+type SongCardProps = {
+ albumCover: string;
+ songTitle: string;
+ artistName: string;
+ songId: number
+}
+
+const SongCard = (props: SongCardProps) => {
+ const { albumCover, songTitle, artistName, songId } = props;
+ const navigation = useNavigation();
+ return navigation.navigate('Song', { songId })}>
+ {({ isHovered, isFocused }) => (
+
+
+
+
+ {songTitle}
+
+
+ {artistName}
+
+
+
+ )}
+
+}
+
+export default SongCard;
\ No newline at end of file
diff --git a/front/components/SongCardGrid.tsx b/front/components/SongCardGrid.tsx
new file mode 100644
index 0000000..89ffeb7
--- /dev/null
+++ b/front/components/SongCardGrid.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import SongCard from './SongCard';
+import { FlatGrid } from 'react-native-super-grid';
+import { Heading, VStack } from 'native-base';
+
+type SongCardGrid = {
+ songs: Parameters[0][];
+ maxItemPerRow?: number,
+ heading?: string
+}
+
+const SongCardGrid = (props: SongCardGrid) => {
+ return
+ {props.heading}
+ }
+ spacing={20}
+ />
+
+
+}
+
+export default SongCardGrid;
\ No newline at end of file
diff --git a/front/i18n/Translations.ts b/front/i18n/Translations.ts
index c0a6d94..3093038 100644
--- a/front/i18n/Translations.ts
+++ b/front/i18n/Translations.ts
@@ -1,23 +1,60 @@
export const en = {
welcome: 'Welcome',
+ welcomeMessage: 'Welcome back ',
signoutBtn: 'Sign out',
signinBtn: 'Sign in',
+ changeLanguageBtn: "Change language",
+ searchBtn: "Search",
playBtn: 'Play',
+ songPageBtn: 'Go to song page',
level: 'Level',
chapters: 'Chapters',
bestScore: 'Best Score',
lastScore: 'Last Score',
- play: 'Play'
+ play: 'Play',
+ goNextStep: 'Step Up!',
+ mySkillsToImprove: "My Competencies to work on",
+ recentlyPlayed: 'Recently played',
+ search: 'Search',
+ lastSearched: "Last searched",
+ levelProgress: 'good notes',
+
+ // competencies
+ pedalsCompetency: 'Pedals',
+ rightHandCompetency: 'Right hand',
+ leftHandCompetency: 'Left hand',
+ accuracyCompetency: 'Accuracy',
+ arpegeCompetency: 'Arpeges',
+ chordsCompetency: 'Chords',
+
};
export const fr: typeof en = {
welcome: 'Bienvenue',
+ welcomeMessage: 'Re-Bonjour ',
signoutBtn: 'Se déconnecter',
signinBtn: 'Se connecter',
+ changeLanguageBtn: "Changer la langue",
+ searchBtn: "Rechercher",
playBtn: 'Jouer',
+ songPageBtn: 'Aller sur la page de la chanson',
level: 'Niveau',
chapters: 'Chapitres',
bestScore: 'Meilleur Score',
lastScore: 'Dernier Score',
- play: 'Jouer'
+ play: 'Jouer',
+ goNextStep: "Passer à l'étape supérieure",
+ mySkillsToImprove: 'Mes Competences à améliorer',
+ recentlyPlayed: "Récemment joués",
+ lastSearched: "Dernières recherches",
+ search: 'Rechercher',
+ levelProgress: 'bonnes notes',
+
+ // competencies
+ pedalsCompetency: 'Pédales',
+ rightHandCompetency: 'Main droite',
+ leftHandCompetency: 'Main gauche',
+ accuracyCompetency: 'Précision',
+ arpegeCompetency: 'Arpèges',
+ chordsCompetency: 'Accords',
};
\ No newline at end of file
diff --git a/front/package.json b/front/package.json
index 5d0a705..c7e7b49 100644
--- a/front/package.json
+++ b/front/package.json
@@ -36,6 +36,7 @@
"react-native": "0.68.2",
"react-native-safe-area-context": "4.2.4",
"react-native-screens": "~3.11.1",
+ "react-native-super-grid": "^4.6.1",
"react-native-svg": "12.3.0",
"react-native-testing-library": "^6.0.0",
"react-native-web": "0.17.7",
diff --git a/front/views/HomeView.test.tsx b/front/views/HomeView.test.tsx
index bf0fe2c..e50b902 100644
--- a/front/views/HomeView.test.tsx
+++ b/front/views/HomeView.test.tsx
@@ -3,7 +3,7 @@ import { Provider } from 'react-redux';
import store from '../state/Store';
import { fireEvent, render, screen } from '@testing-library/react-native';
-import HomeView from '../views/HomeView';
+import HomeView from './HomeView';
import { en, fr } from '../i18n/Translations';
describe('', () => {
diff --git a/front/views/HomeView.tsx b/front/views/HomeView.tsx
index 3a3d0e3..951e135 100644
--- a/front/views/HomeView.tsx
+++ b/front/views/HomeView.tsx
@@ -1,34 +1,124 @@
-import { useNavigation } from "@react-navigation/native";
import React from "react";
-import { Center, Button, Text } from "native-base";
-import { useDispatch, useSelector } from "../state/Store";
-import { AvailableLanguages, DefaultLanguage, translate } from "../i18n/i18n";
-import { useLanguage } from "../state/LanguageSlice";
-import { unsetUserToken } from "../state/UserSlice";
+import { useQuery } from "react-query";
+import API from "../API";
+import LoadingComponent from "../components/Loading";
+import { Box, ScrollView, Flex, useBreakpointValue, Text, VStack, Progress, Button, useTheme, Heading, Divider } from 'native-base';
+import { useNavigation } from "@react-navigation/native";
+import SongCardGrid from '../components/SongCardGrid';
+import CompetenciesTable from '../components/CompetenciesTable'
+import { translate } from "../i18n/i18n";
+
+const ProgressBar = ({ xp }: { xp: number}) => {
+ const level = Math.floor(xp / 1000);
+ const nextLevel = level + 1;
+ const nextLevelThreshold = nextLevel * 1000;
+ const progessValue = 100 * xp / nextLevelThreshold;
-const HomeView = () => {
- const dispatch = useDispatch();
- const navigation = useNavigation();
- const language: AvailableLanguages = useSelector((state) => state.language.value);
return (
-
- This is the Home Screen
-
-
-
- Current language: {language}
-
+
+ {`${translate('level')} ${level}`}
+
+
+
+ {xp} / {nextLevelThreshold} {translate('levelProgress')}
+
);
}
+const HomeView = () => {
+ const theme = useTheme();
+ const navigation = useNavigation();
+ const screenSize = useBreakpointValue({ base: 'small', md: "big"});
+ const flexDirection = useBreakpointValue({ base: 'column', xl: "row"});
+ const userQuery = useQuery(['user'], () => API.getUserInfo());
+
+ if (!userQuery.data) {
+ return
+
+
+ }
+ return
+
+
+
+ {`${translate('welcome')} ${userQuery.data.name}!`}
+
+
+
+
+
+
+
+ ({
+ albumCover: "",
+ songTitle: "Song",
+ artistName: "Artist",
+ songId: 1
+ }))}
+ />
+
+
+
+ {translate('mySkillsToImprove')}
+
+
+
+
+
+
+
+
+ ({
+ albumCover: "",
+ songTitle: "Song",
+ artistName: "Artist",
+ songId: 1
+ }))}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ({
+ albumCover: "",
+ songTitle: "Song",
+ artistName: "Artist",
+ songId: 1
+ }))}
+ />
+
+
+
+
+
+
+
+}
+
export default HomeView;
diff --git a/front/views/SongLobbyView.tsx b/front/views/SongLobbyView.tsx
index 7b0d3d3..c8fbe57 100644
--- a/front/views/SongLobbyView.tsx
+++ b/front/views/SongLobbyView.tsx
@@ -2,7 +2,7 @@ import { useRoute } from "@react-navigation/native";
import { Button, Divider, Box, Center, Image, Text, VStack, PresenceTransition, Icon } from "native-base";
import API from "../API";
import { useQuery } from 'react-query';
-import LoadingComponent from "../components/loading";
+import LoadingComponent from "../components/Loading";
import React, { useEffect, useState } from "react";
import logo from '../assets/cover.png';
import { translate } from "../i18n/i18n";
diff --git a/front/yarn.lock b/front/yarn.lock
index 68a597d..eae09d3 100644
--- a/front/yarn.lock
+++ b/front/yarn.lock
@@ -8201,6 +8201,13 @@ react-native-screens@~3.11.1:
react-freeze "^1.0.0"
warn-once "^0.1.0"
+react-native-super-grid@^4.6.1:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/react-native-super-grid/-/react-native-super-grid-4.6.1.tgz#620a59e98375dd5138d3e6618991d09e93cbe318"
+ integrity sha512-YEKN//TT3DZlbz+1m6YqnclYS+T/Qn2ELrZ0fjoXzB2U/AQoBflvtw0VsJkcPkf3RGWLbD1GKbKN6Hz9fPCVfg==
+ dependencies:
+ prop-types "^15.6.0"
+
react-native-svg@12.3.0:
version "12.3.0"
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.3.0.tgz#40f657c5d1ee366df23f3ec8dae76fd276b86248"