Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions front/assets/translations/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@
"radiusRange": "Radius range: %{range} km",
"delete": "Delete availability",
"deleteConfirm": "Are you sure you want to delete this availability?"
},
"requestDeletion": {
"button": "Delete my profile",
"buttonDisabled": "Profile deletion requested",
"title": "Request profile deletion",
"message": "Are you sure you want to request the deletion of your profile?\n\nAn administrator will manually review your request before deleting your profile.",
"confirm": "Request deletion"
},
"admin": {
"buttonTitle": "Administration panel",
"buttonSubtitle": "Administration of the platform"
}
},
"login": {
Expand All @@ -149,5 +160,12 @@
},
"applications": {
"applications": "Applications"
},
"admin": {
"userDeletion": {
"headerTitle": "User deletion",
"dialogTitle": "Delete user",
"dialogMessage": "Are you sure you want to delete %{name}?"
}
}
}
18 changes: 18 additions & 0 deletions front/assets/translations/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@
"radiusRange": "Rayon de recherche : %{range} km",
"delete": "Supprimer la disponibilité",
"deleteConfirm": "Voulez-vous vraiment supprimer cette disponibilité?"
},
"requestDeletion": {
"button": "Supprimer mon profil",
"buttonDisabled": "Suppression du profil demandée",
"title": "Demande de suppression de profil",
"message": "Êtes-vous sûr de vouloir supprimer votre profil ?\n\nUn administrateur devra valider votre demande avant que votre profil ne soit supprimé.",
"confirm": "Confirmer la demande"
},
"admin": {
"buttonTitle": "Panel d'administration",
"buttonSubtitle": "Administration de la plateforme"
}
},
"login": {
Expand All @@ -149,5 +160,12 @@
},
"applications": {
"applications": "Candidatures"
},
"admin": {
"userDeletion": {
"headerTitle": "Suppression d'utilisateurs",
"dialogTitle": "Supprimer un utilisateur",
"dialogMessage": "Êtes-vous sûr de vouloir supprimer %{name} ?"
}
}
}
21 changes: 21 additions & 0 deletions front/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,28 @@
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.17",
"@reduxjs/toolkit": "^2.1.0",
"@types/base-64": "^1.0.2",
"@types/color": "^3.0.6",
"@types/react": "~18.2.55",
"base-64": "^1.0.0",
"color": "^4.2.3",
"deepmerge": "^4.3.1",
"expo": "~50.0.6",
"expo-auth-session": "~5.4.0",
"expo-crypto": "~12.8.0",
"expo-document-picker": "~11.10.1",
"expo-file-system": "~16.0.6",
"expo-font": "~11.10.2",
"expo-image-picker": "~14.7.1",
"expo-localization": "~14.8.3",
"expo-secure-store": "~12.8.1",
"expo-sharing": "~11.10.0",
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"expo-system-ui": "~2.9.3",
"expo-web-browser": "~12.8.2",
"i18n-js": "^4.3.2",
"jwt-decode": "^4.0.0",
"react": "^18.2.0",
"react-native": "0.73.4",
"react-native-pager-view": "6.2.3",
Expand All @@ -45,10 +51,7 @@
"react-native-screens": "~3.29.0",
"react-native-tab-view": "^3.5.2",
"react-redux": "^9.1.0",
"typescript": "^5.3.3",
"expo-document-picker": "~11.10.1",
"expo-sharing": "~11.10.0",
"expo-file-system": "~16.0.6"
"typescript": "^5.3.3"
},
"devDependencies": {
"@babel/core": "^7.23.9",
Expand Down
67 changes: 67 additions & 0 deletions front/src/components/administration/UserRequestingDeletionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { FC } from 'react';
import { StyleSheet, View } from 'react-native';
import { Icon, Text, TouchableRipple } from 'react-native-paper';

import ProfileHeaderDescription from '@/components/profile/header/ProfileHeaderDescription';
import { Profile } from '@/models/entities/profile';

/**
* The styles for the UserRequestingDeletionItem component.
*/
const styles = StyleSheet.create({
container: {
alignItems: 'center',
flexDirection: 'row',
gap: 4,
},
iconContainer: {
paddingHorizontal: 8,
},
nameContainer: {
flex: 1,
flexDirection: 'column',
gap: 8,
},
});

/**
* The props for the UserRequestingDeletionList component.
*/
type UserRequestingDeletionItemProps = {
/**
* The profile to display.
*/
profile: Profile;

/**
* The function to call when an item is pressed.
*/
onItemPress?: (profile: Profile) => void;
};

/**
* Displays a user requesting their deletion.
* @constructor
*/
export const UserRequestingDeletionItem: FC<
UserRequestingDeletionItemProps
> = ({ profile, onItemPress }) => {
return (
<TouchableRipple onPress={() => onItemPress?.(profile)}>
<View style={styles.container}>
<View style={styles.nameContainer}>
<Text variant='headlineSmall'>
{profile.firstName} {profile.lastName}
</Text>
<ProfileHeaderDescription shortBiography={profile.shortBiography} />
</View>

<View style={styles.iconContainer}>
<Icon size={30} source='trash-can-outline' />
</View>
</View>
</TouchableRipple>
);
};

export default UserRequestingDeletionItem;
58 changes: 58 additions & 0 deletions front/src/components/administration/UserRequestingDeletionList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { FC } from 'react';
import { StyleSheet, View } from 'react-native';
import { Divider } from 'react-native-paper';

import UserRequestingDeletionItem from '@/components/administration/UserRequestingDeletionItem';
import { Profile } from '@/models/entities/profile';

/**
* The styles for the ExperienceList component.
*/
const styles = StyleSheet.create({
divider: {
height: 1,
marginVertical: 8,
width: '100%',
},
});

/**
* The props for the UserRequestingDeletionList component.
*/
type UserRequestingDeletionListProps = {
/**
* The list of profiles to display.
*/
profiles: Profile[];

/**
* The function to call when an item is pressed.
*/
onItemPress?: (profile: Profile) => void;
};

/**
* Displays a list of users requesting their deletion.
* @constructor
*/
const UserRequestingDeletionList: FC<UserRequestingDeletionListProps> = ({
profiles,
onItemPress,
}) => {
return (
<View>
{profiles?.map((profile) => (
<View key={profile.id}>
<UserRequestingDeletionItem
profile={profile}
onItemPress={onItemPress}
/>

<Divider style={styles.divider} />
</View>
))}
</View>
);
};

export default UserRequestingDeletionList;
1 change: 0 additions & 1 deletion front/src/components/availabilities/AvailabilityList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ type AvailabilityListProps = {
/**
* The function to call when the delete button of an item is pressed.
*/

onItemDeletePress?: (availability: Availability) => void;
};

Expand Down
14 changes: 12 additions & 2 deletions front/src/components/login/LogoutButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as AuthSession from 'expo-auth-session';
import { TokenTypeHint, useAutoDiscovery } from 'expo-auth-session';
import { FC, useCallback } from 'react';
import { ViewStyle } from 'react-native';
import { Button } from 'react-native-paper';

import { logout } from '@/store/features/authenticationSlice';
Expand All @@ -15,13 +16,18 @@ type LogoutButtonProps = {
* The mode of the button.
*/
mode?: 'text' | 'outlined' | 'contained' | 'elevated' | 'contained-tonal';

/**
* The style of the container.
*/
style?: ViewStyle;
};

/**
* The button for logging out of the app.
* @constructor
*/
const LogoutButton: FC<LogoutButtonProps> = ({ mode }) => {
const LogoutButton: FC<LogoutButtonProps> = ({ mode, style }) => {
// Store hooks
const authState = useAppSelector((state) => state.auth);
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -61,7 +67,11 @@ const LogoutButton: FC<LogoutButtonProps> = ({ mode }) => {
}, [authState, discovery, dispatch, oidcClientId]);

return (
<Button mode={mode ?? 'contained'} onPress={handleLogoutPress}>
<Button
mode={mode ?? 'contained'}
onPress={handleLogoutPress}
style={style}
>
{i18n.t('login.logout')}
</Button>
);
Expand Down
22 changes: 22 additions & 0 deletions front/src/components/profile/ProfileContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import AvailabilityList from '@/components/availabilities/AvailabilityList';
import ProfileContactInfos from '@/components/profile/ProfileContactInfos';
import ProfileFooterButtons from '@/components/profile/ProfileFooterButtons';
import ProfileHeader from '@/components/profile/header/ProfileHeader';
import BigButton from '@/components/utils/BigButton';
import { Availability } from '@/models/entities/availability';
import { Profile } from '@/models/entities/profile';
import i18n from '@/utils/i18n';

/**
* The styles for the ProfilePage component.
Expand Down Expand Up @@ -45,6 +47,11 @@ type ProfileProps = {
*/
availabilities: Availability[];

/**
* Whether to show access to the administration panel.
*/
showAdmin: boolean;

/**
* The function to call when the experiences button is pressed.
*/
Expand All @@ -54,6 +61,11 @@ type ProfileProps = {
* The function to call when the references button is pressed.
*/
onReferencesPress?: () => void;

/**
* The function to call when the admin button is pressed.
*/
onAdminPress?: () => void;
};

/**
Expand All @@ -64,8 +76,10 @@ const ProfileContents: FC<ProfileProps> = ({
profile,
profilePictureUrl,
availabilities,
showAdmin,
onExperiencesPress,
onReferencesPress,
onAdminPress,
}) => {
return (
<ScrollView
Expand All @@ -90,6 +104,14 @@ const ProfileContents: FC<ProfileProps> = ({
onReferencesPress={onReferencesPress}
style={styles.footerButtons}
/>

{showAdmin && (
<BigButton
title={i18n.t('profile.admin.buttonTitle')}
subtitle={i18n.t('profile.admin.buttonSubtitle')}
onPress={onAdminPress}
/>
)}
</ScrollView>
);
};
Expand Down
Loading