Skip to content

Commit

Permalink
refactor(api): update club list to new api
Browse files Browse the repository at this point in the history
  • Loading branch information
ignyx committed Jul 27, 2024
1 parent 1de700f commit 77a0c4b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 74 deletions.
7 changes: 4 additions & 3 deletions src/components/Lists/Clubs/ClubListHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ function ClubListHeader(props: PropsType) {

const getCategoriesRender = () => {
const final: Array<React.ReactNode> = [];
props.categories.forEach((cat: string) => {
final.push(getChipRender(cat, cat));
});
if (props.categories)
props.categories.forEach((cat: string) => {
final.push(getChipRender(cat, cat));
});
return final;
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/Lists/Clubs/ClubListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import * as React from 'react';
import { Avatar, Chip, List, useTheme } from 'react-native-paper';
import { StyleSheet, View } from 'react-native';
import type { ClubType } from '../../../screens/Amicale/Clubs/ClubListScreen';
import type { Club } from '../../../screens/Amicale/Clubs/ClubListScreen';
import GENERAL_STYLES from '../../../constants/Styles';

type Props = {
onPress: () => void;
item: ClubType;
item: Club;
height: number;
};

Expand Down Expand Up @@ -53,7 +53,7 @@ const styles = StyleSheet.create({

function ClubListItem(props: Props) {
const theme = useTheme();
const hasManagers: boolean = props.item.responsibles.length > 0;
const hasManagers: boolean = props.item.respo.length > 0;

const getCategoriesRender = () => {
const final: Array<React.ReactNode> = [];
Expand Down
101 changes: 52 additions & 49 deletions src/screens/Amicale/Clubs/ClubDisplayScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
import i18n from 'i18n-js';
import CustomHTML from '../../../components/Overrides/CustomHTML';
import { TAB_BAR_HEIGHT } from '../../../components/Tabbar/CustomTabBar';
import type { ClubCategoryType, ClubType } from './ClubListScreen';
import type { Club, ClubRespo } from './ClubListScreen';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import ImageGalleryButton from '../../../components/Media/ImageGalleryButton';
import RequestScreen from '../../../components/Screens/RequestScreen';
Expand Down Expand Up @@ -77,6 +77,24 @@ const styles = StyleSheet.create({
},
});

type ResponseData = {
isMember: boolean; // Whether the user is a member of this club, `false` if user is not logged in
pendingIncomingInvitation: boolean; // Whether the user has been invited to join this club, `false` if user is not logged in, `false` if user is already a member
pendingOutgoingRequest: boolean; // Whether the user has requested to join this club, `false` if user is not logged in, `false` if user is already a member
canJoin: boolean; // Whether the user is able to join this club, `false` if joining is disabled or not yet implemented, `false` if user is not logged in, `false` if user is already a member
isManager: boolean; // Whether the user can view member list, invite and remove members, `false` if user is not logged in
role:
| 'president'
| 'vice-president'
| 'treasurer'
| 'secretary'
| 'respo'
| 'member'
| 'none'; // User's role inside the club
responsibility?: string; // If `role` is set to `respo`, this indicates the title taken by the member within the club
club: Club; // Reference to Club type
};

/**
* Class defining a club event information page.
* If called with data and categories navigation parameters, will use those to display the data.
Expand All @@ -86,56 +104,30 @@ function ClubDisplayScreen(props: Props) {
const navigation = useNavigation();
const theme = useTheme();

const [displayData, setDisplayData] = useState<ClubType | undefined>(
props.route.params.type === 'full' ? props.route.params.data : undefined
);
const categories =
props.route.params.type === 'full'
? props.route.params.categories
: undefined;
const [displayData, setDisplayData] = useState<ResponseData | undefined>();
const clubId =
props.route.params.type === 'full'
? props.route.params.data.id
: props.route.params.clubId;

/**
* Gets the name of the category with the given ID
*
* @param id The category's ID
* @returns {string|*}
*/
const getCategoryName = (id: number): string => {
let categoryName = '';
if (categories) {
categories.forEach((item: ClubCategoryType) => {
if (id === item.id) {
categoryName = item.name;
}
});
}
return categoryName;
};

/**
* Gets the view for rendering categories
*
* @param categories The categories to display (max 2)
* @returns {null|*}
*/
const getCategoriesRender = (c: Array<number | null>) => {
const getCategoriesRender = (categories: Array<string>) => {
if (!categories) {
return null;
}

const final: Array<React.ReactNode> = [];
c.forEach((cat: number | null) => {
if (cat != null) {
final.push(
<Chip style={styles.category} key={cat}>
{getCategoryName(cat)}
</Chip>
);
}
categories.forEach((category: string) => {
final.push(
<Chip style={styles.category} key={category}>
{category}
</Chip>
);
});
return <View style={styles.categoryContainer}>{final}</View>;
};
Expand All @@ -147,10 +139,17 @@ function ClubDisplayScreen(props: Props) {
* @param email The club contact email
* @returns {*}
*/
const getManagersRender = (managers: Array<string>, email: string | null) => {
const getManagersRender = (
managers: Array<ClubRespo>,
email: string | null
) => {
const managersListView: Array<React.ReactNode> = [];
managers.forEach((item: string) => {
managersListView.push(<Paragraph key={item}>{item}</Paragraph>);
managers.forEach((respo: ClubRespo) => {
managersListView.push(
<Paragraph
key={respo.name}
>{`${respo.name} (${respo.role})`}</Paragraph>
);
});
const hasManagers = managers.length > 0;
return (
Expand Down Expand Up @@ -214,29 +213,32 @@ function ClubDisplayScreen(props: Props) {
);
};

const getScreen = (data: ClubType | undefined) => {
if (data) {
const getScreen = (response: ResponseData | undefined) => {
const club = response?.club;

if (club) {
console.log(club);
return (
<CollapsibleScrollView style={styles.scroll} hasTab>
{getCategoriesRender(data.category)}
{data.logo !== null ? (
{getCategoriesRender(club.categories)}
{club.logo !== null ? (
<ImageGalleryButton
images={[{ url: data.logo }]}
images={[{ url: club.logo }]}
style={styles.imageButton}
/>
) : (
<View />
)}

{data.description !== null ? (
{club.description !== null ? (
// Surround description with div to allow text styling if the description is not html
<Card.Content>
<CustomHTML html={data.description} />
<CustomHTML html={club.description} />
</Card.Content>
) : (
<View />
)}
{getManagersRender(data.responsibles, data.email)}
{getManagersRender(club.respo, club.mail)}
</CollapsibleScrollView>
);
}
Expand All @@ -249,9 +251,10 @@ function ClubDisplayScreen(props: Props) {
}
}, [displayData, navigation]);

const request = useAuthenticatedRequest<ClubType>('clubs/info', {
id: clubId,
});
const request = useAuthenticatedRequest<ResponseData>(
'clubs/club?id=' + clubId,
'GET'
);

return (
<RequestScreen
Expand Down
37 changes: 18 additions & 19 deletions src/screens/Amicale/Clubs/ClubListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,28 @@ import { useNavigation } from '@react-navigation/native';
import { useAuthenticatedRequest } from '../../../context/loginContext';
import { MainRoutes } from '../../../navigation/MainNavigator';

export type ClubRespoType = {
export type ClubRespo = {
name: string;
role: string;
};

export type ClubType = {
id: number;
name: string;
mail: string | null;
website: string | null;
instagram: string | null;
discord: string | null;
description: string | null;
type: number;
categories: Array<string>;
respo: Array<string>;
responsibles: Array<ClubRespoType>;
logo: string | null;
export type Club = {
id: number; // minimum: 0
name: string; // Unstyled string, maxLength: 255
mail: string; // email format, maxLength: 255
website: string; // url format, maxLength: 255
instagram: string; // maxLength: 255
discord: string; // url format, maxLength: 255
description: string; // HTML description, maxLength: 255
type: number; // 0: Club de l'Amicale, 1: Association, 2: Organisateur d'event, minimum: 0
categories: string[]; // array of strings, maxLength: 255
respo: ClubRespo[];
logo: string; // Url to logo image, maxLength: 255
};

type ResponseType = {
categories: Array<string>;
clubs: Array<ClubType>;
clubs: Array<Club>;
};

const LIST_ITEM_HEIGHT = 96;
Expand Down Expand Up @@ -113,7 +112,7 @@ function ClubListScreen() {
*
* @param item The article pressed
*/
const onListItemPress = (item: ClubType) => {
const onListItemPress = (item: Club) => {
navigation.navigate(MainRoutes.ClubInformation, {
type: 'full',
data: item,
Expand Down Expand Up @@ -153,7 +152,7 @@ function ClubListScreen() {
}
};

const getRenderItem = ({ item }: { item: ClubType }) => {
const getRenderItem = ({ item }: { item: Club }) => {
const onPress = () => {
onListItemPress(item);
};
Expand All @@ -165,7 +164,7 @@ function ClubListScreen() {
return null;
};

const keyExtractor = (item: ClubType): string => item.id.toString();
const keyExtractor = (item: Club): string => item.id.toString();

/**
* Updates the search string and category filter, saving them to the State.
Expand Down Expand Up @@ -205,7 +204,7 @@ function ClubListScreen() {
* @param item The club to check
* @returns {boolean}
*/
const shouldRenderItem = (item: ClubType): boolean => {
const shouldRenderItem = (item: Club): boolean => {
let shouldRender =
currentlySelectedCategories.length === 0 ||
isItemInCategoryFilter(currentlySelectedCategories, item.categories);
Expand Down

0 comments on commit 77a0c4b

Please sign in to comment.