Merge branch 'feature/adc/#243-leaderboard' into feat/adc/search-view-v2

This commit is contained in:
danis
2023-12-01 15:03:26 +01:00
5 changed files with 173 additions and 100 deletions
+1 -1
View File
@@ -90,7 +90,7 @@ const protectedRoutes = () =>
}, },
Leaderboard: { Leaderboard: {
component: Leaderboardiew, component: Leaderboardiew,
options: { title: translate('leaderboardTitle') }, options: { title: translate('leaderboardTitle'), headerShown: false },
link: '/leaderboard', link: '/leaderboard',
}, },
Error: { Error: {
+1 -1
View File
@@ -13,7 +13,7 @@ const menu = [
{ type: 'main', title: 'menuProfile', icon: User, link: 'User' }, { type: 'main', title: 'menuProfile', icon: User, link: 'User' },
{ type: 'main', title: 'menuMusic', icon: Music, link: 'Music' }, { type: 'main', title: 'menuMusic', icon: Music, link: 'Music' },
{ type: 'main', title: 'menuSearch', icon: SearchNormal1, link: 'Search' }, { type: 'main', title: 'menuSearch', icon: SearchNormal1, link: 'Search' },
{ type: 'main', title: 'menuLeaderBoard', icon: Cup, link: 'Score' }, { type: 'main', title: 'menuLeaderBoard', icon: Cup, link: 'Leaderboard' },
{ type: 'sub', title: 'menuSettings', icon: Setting2, link: 'Settings' }, { type: 'sub', title: 'menuSettings', icon: Setting2, link: 'Settings' },
] as const; ] as const;
+3 -1
View File
@@ -18,6 +18,7 @@ export const UserValidator = yup
googleID: yup.string().required().nullable(), googleID: yup.string().required().nullable(),
isGuest: yup.boolean().required(), isGuest: yup.boolean().required(),
partyPlayed: yup.number().required(), partyPlayed: yup.number().required(),
totalScore: yup.number().required(),
}) })
.concat(ModelValidator); .concat(ModelValidator);
@@ -30,6 +31,7 @@ export const UserHandler: ResponseHandler<yup.InferType<typeof UserValidator>, U
premium: false, premium: false,
data: { data: {
gamesPlayed: value.partyPlayed as number, gamesPlayed: value.partyPlayed as number,
totalScore: value.totalScore as number,
xp: 0, xp: 0,
createdAt: new Date('2023-04-09T00:00:00.000Z'), createdAt: new Date('2023-04-09T00:00:00.000Z'),
avatar: `${API.baseUrl}/users/${value.id}/picture`, avatar: `${API.baseUrl}/users/${value.id}/picture`,
@@ -51,7 +53,7 @@ interface User extends Model {
interface UserData { interface UserData {
gamesPlayed: number; gamesPlayed: number;
xp: number; xp: number;
totalScore: number; totalScore: number;
avatar: string; avatar: string;
createdAt: Date; createdAt: Date;
} }
+1 -1
View File
@@ -122,7 +122,7 @@ const HomeView = (props: RouteProps<{}>) => {
translate={{ translationKey: 'leaderboardTitle' }} translate={{ translationKey: 'leaderboardTitle' }}
colorScheme="primary" colorScheme="primary"
size="sm" size="sm"
onPress={() => navigation.navigate('Leaderboard')} onPress={() => navigation.navigate('Leaderboard', {})}
/> />
<TextButton <TextButton
label={'V2'} label={'V2'}
+167 -96
View File
@@ -1,8 +1,11 @@
import { Box, Heading, useBreakpointValue, ScrollView, Text } from 'native-base'; import { useBreakpointValue, ScrollView, Text } from 'native-base';
import { View, Image } from 'react-native'; import { View, Image } from 'react-native';
import { useQuery } from '../Queries'; import { useQuery } from '../Queries';
import API from '../API'; import API from '../API';
import { Ionicons } from '@expo/vector-icons'; import { LoadingView } from '../components/Loading';
import { useNavigation, RouteProps } from '../Navigation';
import { MedalStar } from 'iconsax-react-native';
import ScaffoldCC from '../components/UI/ScaffoldCC';
import User from '../models/User'; import User from '../models/User';
type PodiumCardProps = { type PodiumCardProps = {
@@ -10,15 +13,21 @@ type PodiumCardProps = {
medalColor: string; medalColor: string;
userAvatarUrl: string; userAvatarUrl: string;
userPseudo: string; userPseudo: string;
userXp: number; userLvl: number;
}; };
const PodiumCardComponent = ({ offset, medalColor, userAvatarUrl, userPseudo, userXp }: PodiumCardProps) => { const PodiumCardComponent = ({
offset,
medalColor,
userAvatarUrl,
userPseudo,
userLvl,
}: PodiumCardProps) => {
return ( return (
<View <View
style={{ style={{
display: 'flex', display: 'flex',
paddingTop: 0 + offset, paddingTop: offset,
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
@@ -43,10 +52,10 @@ const PodiumCardComponent = ({ offset, medalColor, userAvatarUrl, userPseudo, us
borderRadius: 12, borderRadius: 12,
}} }}
/> />
<Ionicons <MedalStar
style={{ position: 'absolute', top: 106, left: 106 }} style={{ position: 'absolute', top: 115, left: 115 }}
name="medal" size="42"
size={24} variant="Bold"
color={medalColor} color={medalColor}
/> />
</View> </View>
@@ -68,22 +77,25 @@ const PodiumCardComponent = ({ offset, medalColor, userAvatarUrl, userPseudo, us
fontWeight: '500', fontWeight: '500',
}} }}
> >
{userXp} LVL {userLvl} LVL
</Text> </Text>
</View> </View>
); );
}; };
type BoardRowProps = { type BoardRowProps = {
userAvatarUrl: string;
userPseudo: string; userPseudo: string;
userXp: number; userLvl: number;
} index: number;
};
const BoardRowComponent = () => { const BoardRowComponent = ({ userAvatarUrl, userPseudo, userLvl, index }: BoardRowProps) => {
return ( return (
<View <View
style={{ style={{
margin: 5, marginVertical: 5,
marginHorizontal: 10,
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
@@ -105,9 +117,14 @@ const BoardRowComponent = () => {
> >
<Image <Image
source={{ source={{
uri: 'https://picsum.photos/50/50', uri: userAvatarUrl,
}}
style={{
width: '100%',
height: '100%',
borderTopLeftRadius: 8,
borderBottomLeftRadius: 8,
}} }}
style={{ width: '100%', height: '100%' }}
/> />
</View> </View>
@@ -115,12 +132,12 @@ const BoardRowComponent = () => {
style={{ style={{
fontSize: 16, fontSize: 16,
fontStyle: 'normal', fontStyle: 'normal',
flex: '1 1 0', flex: 1,
marginHorizontal: 10, marginHorizontal: 10,
fontWeight: '500', fontWeight: '500',
}} }}
> >
Momo est boutain {userPseudo}
</Text> </Text>
<Text <Text
style={{ style={{
@@ -130,7 +147,7 @@ const BoardRowComponent = () => {
marginHorizontal: 10, marginHorizontal: 10,
}} }}
> >
200 LVL {userLvl} LVL
</Text> </Text>
<View <View
style={{ style={{
@@ -151,98 +168,152 @@ const BoardRowComponent = () => {
textAlign: 'center', textAlign: 'center',
}} }}
> >
8 {index + 4}
</Text> </Text>
</View> </View>
</View> </View>
); );
}; };
const dummyScores = [ const Leaderboardiew = (props: RouteProps<Record<string, never>>) => {
{ const navigation = useNavigation();
id: 1, const scoresQuery = useQuery(API.getTopTwentyPlayers());
}, const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
{ const isPhone = screenSize === 'small';
id: 2,
},
{
id: 3,
},
{
id: 4,
},
{
id: 5,
},
{
id: 6,
},
{
id: 7,
},
{
id: 8,
},
{
id: 9,
},
];
const Leaderboardiew = () => { if (scoresQuery.isError) {
const scoresQuery = useQuery(API.getTopTwentyPlayers); navigation.navigate('Error');
return <></>;
}
if (scoresQuery.data === undefined) {
return (
<ScaffoldCC routeName={props.route.name}>
<LoadingView />
</ScaffoldCC>
);
}
return ( return (
<ScrollView style={{ marginBottom: 5 }}> <ScaffoldCC routeName={props.route.name}>
<View <ScrollView style={{ marginBottom: 5 }}>
style={{ <View
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
flex: 1,
flexGrow: 1,
flexShrink: 0,
flexBasis: 0,
alignSelf: 'stretch',
}}
>
<View /** podium view */
style={{ style={{
display: 'flex', display: 'flex',
paddingBottom: 0, flexDirection: 'column',
justifyContent: 'center', alignItems: 'flex-start',
alignItems: 'center', flex: 1,
flexGrow: 1,
flexShrink: 0,
flexBasis: 0,
alignSelf: 'stretch', alignSelf: 'stretch',
flexDirection: 'row',
marginBottom: 20,
}} }}
> >
<PodiumCardComponent {!isPhone ? (
medalColor="#AE84FB" <View /** podium view */
offset={80} style={{
userAvatarUrl={scoresQuery.data?.at(2)?.data.avatar ?? "fake image"} display: 'flex',
userPseudo={scoresQuery.data?.at(2)?.name ?? "Momo"} flexDirection: 'row',
userXp={scoresQuery.data?.at(2)?.data.xp ?? 0} justifyContent: 'center',
/> alignItems: 'center',
<PodiumCardComponent alignSelf: 'stretch',
medalColor="#EAD93C" paddingBottom: 10,
offset={0} marginBottom: 20,
userAvatarUrl={scoresQuery.data?.at(0)?.data.avatar ?? "fake image"} }}
userPseudo={scoresQuery.data?.at(0)?.name ?? "Momo"} >
userXp={scoresQuery.data?.at(0)?.data.xp ?? 0} <PodiumCardComponent
/> medalColor="#AE84FB"
<PodiumCardComponent offset={80}
medalColor="#5F74F7" userAvatarUrl={
offset={60} scoresQuery.data?.at(2)?.data.avatar ??
userAvatarUrl={scoresQuery.data?.at(1)?.data.avatar ?? "fake image"} 'https://picsum.photos/140/140'
userPseudo={scoresQuery.data?.at(1)?.name ?? "Momo"} }
userXp={scoresQuery.data?.at(1)?.data.xp ?? 0} userPseudo={scoresQuery.data?.at(2)?.name ?? '---'}
/> userLvl={scoresQuery.data?.at(2)?.data.totalScore ?? 42}
/>
<PodiumCardComponent
medalColor="#EAD93C"
offset={0}
userAvatarUrl={
scoresQuery.data?.at(0)?.data.avatar ??
'https://picsum.photos/140/140'
}
userPseudo={scoresQuery.data?.at(0)?.name ?? '---'}
userLvl={scoresQuery.data?.at(0)?.data.totalScore ?? 42}
/>
<PodiumCardComponent
medalColor="#5F74F7"
offset={60}
userAvatarUrl={
scoresQuery.data?.at(1)?.data.avatar ??
'https://picsum.photos/140/140'
}
userPseudo={scoresQuery.data?.at(1)?.name ?? '---'}
userLvl={scoresQuery.data?.at(1)?.data.totalScore ?? 42}
/>
</View>
) : (
<View
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'stretch',
}}
>
<PodiumCardComponent
medalColor="#AE84FB"
offset={80}
userAvatarUrl={
scoresQuery.data?.at(0)?.data.avatar ??
'https://picsum.photos/140/140'
}
userPseudo={scoresQuery.data?.at(0)?.name ?? '---'}
userLvl={scoresQuery.data?.at(0)?.data.totalScore ?? 42}
/>
<View
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<PodiumCardComponent
medalColor="#EAD93C"
offset={0}
userAvatarUrl={
scoresQuery.data?.at(1)?.data.avatar ??
'https://picsum.photos/140/140'
}
userPseudo={scoresQuery.data?.at(1)?.name ?? '---'}
userLvl={scoresQuery.data?.at(1)?.data.totalScore ?? 42}
/>
<PodiumCardComponent
medalColor="#5F74F7"
offset={60}
userAvatarUrl={
scoresQuery.data?.at(2)?.data.avatar ??
'https://picsum.photos/140/140'
}
userPseudo={scoresQuery.data?.at(2)?.name ?? '---'}
userLvl={scoresQuery.data?.at(2)?.data.totalScore ?? 42}
/>
</View>
</View>
)}
{scoresQuery.data.slice(3).map((comp: User, index: number) => (
<BoardRowComponent
key={index}
index={index}
userAvatarUrl={comp?.data.avatar ?? 'https://picsum.photos/50/50'}
userLvl={comp?.data.totalScore ?? 42}
userPseudo={comp?.name ?? '---'}
/>
))}
</View> </View>
{dummyScores.map((comp, index) => ( </ScrollView>
<BoardRowComponent /> </ScaffoldCC>
))}
</View>
</ScrollView>
); );
}; };