Skip to content

Commit

Permalink
Club page integration
Browse files Browse the repository at this point in the history
  • Loading branch information
TylerSchaefer4 committed Jun 8, 2024
1 parent 8465922 commit 62702d5
Show file tree
Hide file tree
Showing 10 changed files with 600 additions and 8 deletions.
176 changes: 176 additions & 0 deletions frontend/mobile/app/(app)/(components)/ClubPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
import Animated, {
interpolate,
useAnimatedRef,
useAnimatedStyle,
useScrollViewOffset
} from 'react-native-reanimated';

import { faExternalLink } from '@fortawesome/free-solid-svg-icons';
import {
Club,
Contact,
Event,
PointOfContact as POCProps,
Tag as TagProps
} from '@generatesac/lib';

import {
Box,
Button,
RecruitmentInfo,
SACColors,
Tag,
Text
} from '@/app/(design-system)';
import { ClubIcon } from '@/app/(design-system)/components/ClubIcon/ClubIcon';
import { EventCard } from '@/app/(design-system)/components/EventCard';
import { PointOfContactList } from '@/app/(design-system)/components/PointOfContactCard/PointofContactsList';

import { AnimatedImageBox } from './ClubPageHeader';
import { EventCardList } from './EventCardList';

interface ClubPageProps {
club: Club;
tags: TagProps[];
events: Event[];
contacts: Contact[];
color: SACColors;
pointOfContacts: POCProps[];
}

export const ClubPage: React.FC<ClubPageProps> = ({
club,
tags,
events,
contacts,

Check failure on line 47 in frontend/mobile/app/(app)/(components)/ClubPage.tsx

View workflow job for this annotation

GitHub Actions / Lint

'contacts' is defined but never used. Allowed unused args must match /^_/u
color,
pointOfContacts
}) => {
const { width } = Dimensions.get('window');
const IMG_HEIGHT = width;

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

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

return (
<Box>
<Animated.ScrollView
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
ref={scrollRef}
>
<AnimatedImageBox
uri="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLF3ord7lnV_5Je-pC2AUgUiesHNPcZlpI7A&s"
animatedStyle={imageAnimatedStyle}
/>
<Box rowGap="m" backgroundColor="white" padding="s">
<Box
flexDirection="row"
justifyContent="space-between"
marginTop="negativeXl"
alignItems="center"
>
<ClubIcon imageUrl="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLF3ord7lnV_5Je-pC2AUgUiesHNPcZlpI7A&s" />
<Box width={116}>
<Button color={color} variant="standardButton">
Follow
</Button>
</Box>
</Box>
<Text variant="header-1">{club.name}</Text>
<Box
flexDirection="row"
flexWrap="wrap"
rowGap="xs"
columnGap="s"
>
{tags.map((tag) => (
<Tag color={color} key={tag.id}>
{tag.name}
</Tag>
))}
</Box>
<Box gap="xxs" marginBottom="s">
<Text variant="subheader-1">About Us</Text>
<Text variant="body-1">{club.description}</Text>
</Box>

<Button
variant="iconButton"
icon={faExternalLink}
color={color}
iconPosition="right"
size="sm"
justifyContent="space-between"
flexDirection="row"
onPress={() => Linking.openURL(club.application_link)}
>
<Box paddingBottom="xxxs" paddingTop="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
recruitmentText="Fill out our application"
recruitingType={club.recruitment_type}
isRecruiting={club.is_recruiting}
recruitmentCycle={club.recruitment_cycle}
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>
</Animated.ScrollView>
</Box>
);
};
23 changes: 23 additions & 0 deletions frontend/mobile/app/(app)/(components)/ClubPageHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import Animated from 'react-native-reanimated';

import { Box } from '@/app/(design-system)';

interface AnimatedImageBoxProps {
uri: string;
animatedStyle: any;
}

export const AnimatedImageBox: React.FC<AnimatedImageBoxProps> = ({
uri,
animatedStyle
}) => {
return (
<Box>
<Animated.Image
source={{ uri }}
style={[animatedStyle, { width: '100%', aspectRatio: 1 }]}
/>
</Box>
);
};
42 changes: 42 additions & 0 deletions frontend/mobile/app/(app)/(components)/EventCardList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { FlatList, Pressable } from 'react-native';

import { router } from 'expo-router';

import { Event } from '@generatesac/lib';

import { EventCard } from '@/app/(design-system)/components/EventCard';

interface EventCardListProps {
events: Event[];
}

export const EventCardList: React.FC<EventCardListProps> = ({ events }) => {
const renderEventCard = ({ item }: { item: Event }) => {
return (
<Pressable onPress={() => router.push(`/event/${item.id}`)}>
<EventCard
variant="small"
event={item.name}
club={item.host}
startTime={item.start_time}
endTime={item.end_time}
image="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLF3ord7lnV_5Je-pC2AUgUiesHNPcZlpI7A&s"
logo="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT800M6T7YVq_f6W49g_UNL29US7gC63nTitg&s"
/>
</Pressable>
);
};
return (
<FlatList
showsHorizontalScrollIndicator={false}
horizontal
contentContainerStyle={{
gap: 15,
paddingBottom: 40
}}
data={events}
renderItem={renderEventCard}
keyExtractor={(item) => item.id}
/>
);
};
Loading

0 comments on commit 62702d5

Please sign in to comment.