Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: event & club preview components #1034

Merged
merged 12 commits into from
Jun 17, 2024
2 changes: 1 addition & 1 deletion frontend/lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@generatesac/lib",
"version": "0.0.170",
"version": "0.0.171",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions frontend/lib/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from "./event";
export * from "./file";
export * from "./pointOfContact";
export * from "./verification";
export * from "./recruitment";
2 changes: 1 addition & 1 deletion frontend/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@fortawesome/react-native-fontawesome": "^0.3.2",
"@generatesac/lib": "0.0.170",
"@generatesac/lib": "0.0.171",
"@gorhom/bottom-sheet": "^4.6.3",
"@hookform/resolvers": "^3.4.2",
"@react-native-async-storage/async-storage": "^1.23.1",
Expand Down
119 changes: 71 additions & 48 deletions frontend/mobile/src/app/(app)/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useRef, useState } from 'react';

Check failure on line 1 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

'useState' is defined but never used
Fixed Show fixed Hide fixed

import { Tabs } from 'expo-router';

Expand All @@ -6,10 +6,13 @@
import { faCalendarDays } from '@fortawesome/free-solid-svg-icons/faCalendarDays';
import { faHouse } from '@fortawesome/free-solid-svg-icons/faHouse';
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';

Check failure on line 9 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Insert `import·BottomSheet·from·'@gorhom/bottom-sheet';⏎`
import { Text } from '@/src/app/(design-system)';
import { EventPreview, Text } from '@/src/app/(design-system)';
import { Box } from '@/src/app/(design-system)';
import { Icon } from '@/src/app/(design-system)/components/Icon/Icon';
import { useAppDispatch, useAppSelector } from '@/src/store/store';

Check failure on line 13 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Replace `useAppDispatch,·useAppSelector·}·from·'@/src/store/store';⏎import·BottomSheet·from·'@gorhom/bottom-sheet` with `setEventShouldPreview·}·from·'@/src/store/slices/eventSlice`
import BottomSheet from '@gorhom/bottom-sheet';
import { setEventShouldPreview } from '@/src/store/slices/eventSlice';

Check failure on line 15 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Replace `setEventShouldPreview·}·from·'@/src/store/slices/eventSlic` with `useAppDispatch,·useAppSelector·}·from·'@/src/store/stor`

interface TabBarLabelProps {
focused: boolean;
Expand All @@ -34,55 +37,75 @@
);

const Layout = () => {
const dispatch = useAppDispatch();
const eventPreviewRef = useRef<BottomSheet>(null);
const clubPreviewRef = useRef<BottomSheet>(null);

Check failure on line 42 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

'clubPreviewRef' is assigned a value but never used
Fixed Show fixed Hide fixed

const { shouldPreview: eventShouldPreview, id: eventId } = useAppSelector((state) => state.event);

Check failure on line 44 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Replace `(state)·=>·state.event` with `⏎········(state)·=>·state.event⏎····`

useEffect(() => {
dispatch(setEventShouldPreview(false));
}, [])

Check failure on line 48 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

React Hook useEffect has a missing dependency: 'dispatch'. Either include it or remove the dependency array

Check failure on line 48 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Insert `;`

useEffect(() => {
if (eventShouldPreview) {
eventPreviewRef.current?.snapToIndex(0);
}
}, [eventShouldPreview]);

Check failure on line 54 in frontend/mobile/src/app/(app)/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / Lint

Delete `⏎`


return (
<Tabs
screenOptions={{
tabBarShowLabel: false,
tabBarStyle: {
borderTopWidth: 1,
borderTopColor: 'gray',
height: 85
}
}}
sceneContainerStyle={{
backgroundColor: 'white'
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Home',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Home' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faHouse })
}}
/>
<Tabs.Screen
name="calendar"
options={{
title: 'Calendar',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Calendar' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faCalendarDays })
<>
<Tabs
screenOptions={{
tabBarShowLabel: false,
tabBarStyle: {
borderTopWidth: 1,
borderTopColor: 'gray',
height: 85
}
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
headerShown: true,
headerTransparent: true,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Profile' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faUser })
sceneContainerStyle={{
backgroundColor: 'white'
}}
/>
</Tabs>
>
<Tabs.Screen
name="index"
options={{
title: 'Home',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Home' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faHouse })
}}
/>
<Tabs.Screen
name="calendar"
options={{
title: 'Calendar',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Calendar' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faCalendarDays })
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
headerShown: true,
headerTransparent: true,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Profile' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faUser })
}}
/>
</Tabs>
<EventPreview eventId={eventId} ref={eventPreviewRef} />
</>
);
};

Expand Down
30 changes: 3 additions & 27 deletions frontend/mobile/src/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
import React from 'react';
import { Pressable, StyleSheet } from 'react-native';

import { router } from 'expo-router';

import { Box, Text } from '@/src/app/(design-system)';
import { EventCard } from '@/src/app/(design-system)/components/EventCard';
import { StyleSheet } from 'react-native';

const HomePage = () => {
const item = {
name: 'Your Event Name',
host: 'Your Club Name',
start_time: new Date(),
end_time: new Date()
};

Check failure on line 5 in frontend/mobile/src/app/(app)/(tabs)/index.tsx

View workflow job for this annotation

GitHub Actions / Lint

Replace `⏎····return·(⏎········<></>⏎····)` with `····return·<></>;`
return (
<Box style={styles.container}>
<Text variant="body-1">Home</Text>
<Pressable onPress={() => router.push(`/event/1`)}>
<EventCard
variant="small"
event={item.name}
club={item.host}
eventId="1"
startTime={item.start_time}
endTime={item.end_time}
image="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLF3ord7lnV_5Je-pC2AUgUiesHNPcZlpI7A&s"
/>
</Pressable>
</Box>
);
<></>
)
};

const styles = StyleSheet.create({
Expand Down
11 changes: 11 additions & 0 deletions frontend/mobile/src/app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ const Layout = () => {
}
}}
/>
<Stack.Screen
name="club"
options={{
headerTitle: '',
headerTransparent: true,
headerShown: false,
headerTitleStyle: {
color: 'white'
}
}}
/>
<Stack.Screen
name="user"
options={{
Expand Down
167 changes: 167 additions & 0 deletions frontend/mobile/src/app/(app)/club/[id].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { Dimensions, Linking } from 'react-native';
import Animated, {
interpolate,
useAnimatedRef,
useAnimatedStyle,
useScrollViewOffset
} from 'react-native-reanimated';

import { Arrow, Box, PageTags, RecruitmentInfo, Tag, Text } from '@/src/app/(design-system)';
Fixed Show fixed Hide fixed
import { SACColors } from '@/src/app/(design-system)';
import { Button } from '@/src/app/(design-system)/components/Button/Button';
import AnimatedImageHeader from '../../(design-system)/components/AnimatedImageHeader/AnimatedImageHeader';
import { ClubIcon } from '../../(design-system)/components/ClubIcon/ClubIcon';
import useClub from '@/src/hooks/useClub';
import { Stack, useLocalSearchParams } from 'expo-router';
import { useAppSelector } from '@/src/store/store';
import { AboutSection } from '../../(design-system)/components/AboutSection/AboutSection';
import { Description } from '../event/components/description';
import { useRef } from 'react';
import BottomSheet from '@gorhom/bottom-sheet';
import { faExternalLink } from '@fortawesome/free-solid-svg-icons';

const color: SACColors = 'darkRed';

const ClubPage = () => {
const { id } = useLocalSearchParams<{ id: string }>();
const { width } = Dimensions.get('window');
const IMG_HEIGHT = width;

const scrollRef = useAnimatedRef<Animated.ScrollView>();
const scrollOffset = useScrollViewOffset(scrollRef);

const bottomSheet = useRef<BottomSheet>(null);

const club = useAppSelector((state) => state.club);
const { setRetriggerFetch, apiLoading, apiError } = useClub(id as string);
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed

const headerAnimatedStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateY: interpolate(
scrollOffset.value,
[-IMG_HEIGHT, 0, IMG_HEIGHT],
[0, 0, -IMG_HEIGHT * 0.75]
)
}
]
};
});

return (
<Box height='100%' backgroundColor='white'>
<Stack.Screen
options={{
headerTitle: '',
headerTransparent: true,
headerShown: true,
headerTitleStyle: {
color: 'white'
},
headerLeft: () => (

Check warning on line 62 in frontend/mobile/src/app/(app)/club/[id].tsx

View workflow job for this annotation

GitHub Actions / Lint

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “ClubPage” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true
<Animated.View style={headerAnimatedStyle}>
<Arrow color={apiError ? 'black' : 'white'} />
</Animated.View>
),
}}
/>
<Animated.ScrollView
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
ref={scrollRef}
>
<AnimatedImageHeader
uri="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLF3ord7lnV_5Je-pC2AUgUiesHNPcZlpI7A&s"
scrollOffset={scrollOffset}
imageHeight={IMG_HEIGHT}
aspectRatio={2.5}
/>
<Box backgroundColor="white">
<Box
flexDirection="row"
justifyContent="space-between"
marginTop="negativeXl"
alignItems="center"
paddingVertical='s'
paddingHorizontal='l'
>
<ClubIcon imageUrl={club.logo as string} />
<Box width={116}>
<Button color={color} size='sm' variant="standardButton">
Follow
</Button>
</Box>
</Box>
<Box marginHorizontal='l' marginVertical='m' gap='m'>
<Text variant="header-1">{club.name}</Text>
<PageTags tags={club.tags} color={color} />
<AboutSection
description={club.description}
onPress={() => bottomSheet.current?.snapToIndex(0)}
type='club'
/>
{club.recruitment?.is_recruiting &&
<Button
variant="iconButton"
icon={faExternalLink}
color={color}
iconPosition="right"
size="sm"
justifyContent="space-between"
flexDirection="row"
onPress={() => Linking.openURL('')}
>
<Box paddingBottom="xxxs" paddingTop="xxs" gap='xxs'>
<Text color="white" variant="body-1">
Application Form
</Text>
<Text color="white" variant="caption-1">
Google Form
</Text>
</Box>
</Button>
}
<Box>
<Text variant="subheader-1">Recruiting</Text>
<RecruitmentInfo
recruitingType={'application'}
isRecruiting={false}
recruitmentCycle={'fallSpring'}
color={color}
/>
</Box>

<Text variant="subheader-1">Upcoming Events</Text>
{/* <EventCard
event={events[0].name}
variant="big"
tags={tags}
club={club.name}
startTime={events[0].start_time}
endTime={events[0].end_time}
logo="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT800M6T7YVq_f6W49g_UNL29US7gC63nTitg&s"
image="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQfT6p6kCen0-GphSDogJRd2KoYjg0-QQWuAw9e5JBIBEVTc3Hxho_UwRsZ0IrEi6Ap5oo&usqp=CAU"
/> */}
<Box height={1} backgroundColor="gray" marginVertical="m" />
{/* <EventCardList events={events} /> */}

<Text variant="subheader-1">Leadership</Text>
{/* <PointOfContactList
contacts={pointOfContacts}
color={color}
/> */}
</Box>
</Box>
</Animated.ScrollView>
<Description
description={club.description as string}
ref={bottomSheet}
type='club'
/>
</Box>
);
};

export default ClubPage;
Loading
Loading