diff --git a/frontend/sac-mobile/app/(app)/(tabs)/search.tsx b/frontend/sac-mobile/app/(app)/(tabs)/search.tsx
index 55f256958..89b989329 100644
--- a/frontend/sac-mobile/app/(app)/(tabs)/search.tsx
+++ b/frontend/sac-mobile/app/(app)/(tabs)/search.tsx
@@ -1,11 +1,23 @@
import React from 'react';
-import { Text, View } from 'react-native';
+import { SafeAreaView, ScrollView, Text, View } from 'react-native';
+import { TextInput } from 'react-native-gesture-handler';
+
+import { Button } from '@/components/button';
const Search = () => {
return (
-
- Search
-
+
+
+ Search
+
+
+
+
+
+
);
};
diff --git a/frontend/sac-mobile/app/(app)/_layout.tsx b/frontend/sac-mobile/app/(app)/_layout.tsx
index 3071cb8e8..48928119d 100644
--- a/frontend/sac-mobile/app/(app)/_layout.tsx
+++ b/frontend/sac-mobile/app/(app)/_layout.tsx
@@ -8,6 +8,74 @@ import { MenuView } from '@react-native-menu/menu';
import { LeftArrow } from '@/components/left-arrow';
+const EventDotsVertical = () => {
+ return (
+ {
+ console.warn(JSON.stringify(nativeEvent));
+ }}
+ actions={[
+ {
+ id: 'share',
+ title: 'Share Event',
+ image: Platform.select({
+ ios: 'square.and.arrow.up',
+ android: 'share-variant'
+ })
+ },
+ {
+ id: 'report',
+ title: 'Report Event',
+ image: Platform.select({
+ ios: 'person.crop.circle.badge.exclamationmark.fill',
+ android: 'person-circle-outline'
+ })
+ }
+ ]}
+ >
+
+
+ );
+};
+
+const ClubDotsVertical = () => {
+ return (
+ {
+ console.warn(JSON.stringify(nativeEvent));
+ }}
+ actions={[
+ {
+ id: 'share',
+ title: 'Share Club',
+ image: Platform.select({
+ ios: 'square.and.arrow.up',
+ android: 'share-variant'
+ })
+ },
+ {
+ id: 'report',
+ title: 'Report Club',
+ image: Platform.select({
+ ios: 'person.crop.circle.badge.exclamationmark.fill',
+ android: 'person-circle-outline'
+ })
+ }
+ ]}
+ >
+
+
+ );
+};
+
const Layout = () => {
return (
@@ -15,8 +83,6 @@ const Layout = () => {
{
),
headerLeft: () => ,
- headerRight: () => {
- return (
- {
- console.warn(JSON.stringify(nativeEvent));
- }}
- actions={[
- {
- id: 'share',
- title: 'Share Event',
- image: Platform.select({
- ios: 'square.and.arrow.up',
- android: 'share-variant'
- })
- },
- {
- id: 'report',
- title: 'Report Event',
- image: Platform.select({
- ios: 'person.crop.circle.badge.exclamationmark.fill',
- android: 'person-circle-outline'
- })
- }
- ]}
- >
-
-
- );
- }
+ headerRight: () =>
}}
/>
{
),
headerLeft: () => ,
- headerRight: () => {
- return (
- {
- console.warn(JSON.stringify(nativeEvent));
- }}
- actions={[
- {
- id: 'share',
- title: 'Share Club',
- image: Platform.select({
- ios: 'square.and.arrow.up',
- android: 'share-variant'
- })
- },
- {
- id: 'report',
- title: 'Report Club',
- image: Platform.select({
- ios: 'person.crop.circle.badge.exclamationmark.fill',
- android: 'person-circle-outline'
- })
- }
- ]}
- >
-
-
- );
- }
+ headerRight: () =>
}}
/>
diff --git a/frontend/sac-mobile/app/(app)/club/[id].tsx b/frontend/sac-mobile/app/(app)/club/[id].tsx
index 5c2e6a67a..73112c17c 100644
--- a/frontend/sac-mobile/app/(app)/club/[id].tsx
+++ b/frontend/sac-mobile/app/(app)/club/[id].tsx
@@ -1,19 +1,36 @@
import React from 'react';
-import { SafeAreaView, Text } from 'react-native';
+import { Text, View } from 'react-native';
-import { Link, Stack, useLocalSearchParams } from 'expo-router';
+import { Stack, useLocalSearchParams } from 'expo-router';
+
+import { useClub } from '@/hooks/use-club';
const ClubPage = () => {
const { id } = useLocalSearchParams<{ id: string }>();
+ const { data: club, isLoading, error } = useClub(id);
+
+ if (isLoading) {
+ return Loading...;
+ }
+
+ if (error) {
+ return Error: {error.message};
+ }
+
+ if (!club) {
+ return Club not found;
+ }
+
return (
-
-
- ClubPage
-
- FAQ
-
-
+ <>
+
+
+ {club.name}
+ {club.recruitment_cycle}
+ {club.application_link}
+
+ >
);
};
diff --git a/frontend/sac-mobile/app/(app)/event/[id].tsx b/frontend/sac-mobile/app/(app)/event/[id].tsx
index 84e5a7fa8..64831e3dd 100644
--- a/frontend/sac-mobile/app/(app)/event/[id].tsx
+++ b/frontend/sac-mobile/app/(app)/event/[id].tsx
@@ -1,29 +1,32 @@
-import React from 'react';
+import React, { useRef } from 'react';
import { ScrollView, Text, View } from 'react-native';
import { Stack, useLocalSearchParams } from 'expo-router';
+import BottomSheet from '@gorhom/bottom-sheet';
+
import { AllHosts } from '@/app/(app)/event/_components/all-hosts';
import { TagList } from '@/components/all-tags';
import { Button } from '@/components/button';
import { Description } from '@/components/description';
-import { useAuthStore } from '@/hooks/use-auth';
+import { Title } from '@/components/title';
import { useEvent } from '@/hooks/use-event';
-import { Title } from '../_components/title';
import { EventHeader } from './_components/event-header';
import { EventLocation } from './_components/event-location';
import { EventTime } from './_components/event-time';
import { HostNames } from './_components/host-names';
import { LocationView } from './_components/location-view';
+import RSVPBottomSheet from './_components/rsvp-bottom-sheet';
// TODO: handle link OR location
const EventPage = () => {
const { id } = useLocalSearchParams<{ id: string }>();
- const { user } = useAuthStore();
const { data: event, isLoading, error } = useEvent(id);
+ const ref = useRef(null);
+
if (error) {
console.error(error);
return Error fetching event;
@@ -41,14 +44,12 @@ const EventPage = () => {
return (
<>
-
+
-
+
@@ -84,6 +85,7 @@ const EventPage = () => {
+
>
);
};
diff --git a/frontend/sac-mobile/app/(app)/event/_components/event-header.tsx b/frontend/sac-mobile/app/(app)/event/_components/event-header.tsx
index 094661de5..6003a6d75 100644
--- a/frontend/sac-mobile/app/(app)/event/_components/event-header.tsx
+++ b/frontend/sac-mobile/app/(app)/event/_components/event-header.tsx
@@ -1,10 +1,21 @@
+import { forwardRef } from 'react';
import { Platform, View } from 'react-native';
+import BottomSheet from '@gorhom/bottom-sheet';
import { MenuView } from '@react-native-menu/menu';
import { Button } from '@/components/button';
-const EventHeader = () => {
+type Ref = BottomSheet;
+
+const EventHeader = forwardRef[((_, ref) => {
+ if (!ref) {
+ return null;
+ }
+
+ // @ts-ignore
+ const handleOpenPress = () => ref.current?.snapToIndex(0);
+
return (
@@ -51,9 +62,18 @@ const EventHeader = () => {
RSVP
+
+
);
-};
+});
export { EventHeader };
diff --git a/frontend/sac-mobile/app/(app)/event/_components/location-view.tsx b/frontend/sac-mobile/app/(app)/event/_components/location-view.tsx
index 647a6ef61..abc882879 100644
--- a/frontend/sac-mobile/app/(app)/event/_components/location-view.tsx
+++ b/frontend/sac-mobile/app/(app)/event/_components/location-view.tsx
@@ -1,9 +1,8 @@
import React from 'react';
-import { Image, Linking, Text, TouchableOpacity, View } from 'react-native';
+import { Linking, Text, TouchableOpacity, View } from 'react-native';
+import MapView from 'react-native-maps';
import { createOpenLink } from 'react-native-open-maps';
-import { useAssets } from 'expo-asset';
-
import { Button } from '@/components/button';
type LocationViewProps = {
@@ -12,16 +11,9 @@ type LocationViewProps = {
};
const LocationView = ({ location, meetingLink }: LocationViewProps) => {
- const [assets, error] = useAssets([
- require('@/assets/images/placeholder_location.png')
- ]);
const coordinates = { latitude: 42.3393326, longitude: -71.0869942 };
const openMap = createOpenLink({ ...coordinates });
- if (error) {
- console.error(error);
- }
-
return (
<>
@@ -52,13 +44,15 @@ const LocationView = ({ location, meetingLink }: LocationViewProps) => {
)}
- {assets ? (
-
- ) : null}
+
>
);
diff --git a/frontend/sac-mobile/app/(app)/event/_components/rsvp-bottom-sheet.tsx b/frontend/sac-mobile/app/(app)/event/_components/rsvp-bottom-sheet.tsx
new file mode 100644
index 000000000..e397d2c8a
--- /dev/null
+++ b/frontend/sac-mobile/app/(app)/event/_components/rsvp-bottom-sheet.tsx
@@ -0,0 +1,56 @@
+import React, { forwardRef, useCallback } from 'react';
+import { Text, View } from 'react-native';
+
+import BottomSheet, { BottomSheetBackdrop } from '@gorhom/bottom-sheet';
+
+import { Button } from '@/components/button';
+
+type Ref = BottomSheet;
+
+const RSVPBottomSheet = forwardRef][((_, ref) => {
+ const snapPoints = ['35%'];
+
+ const renderBackdrop = useCallback(
+ (props: any) => (
+
+ ),
+ []
+ );
+
+ // @ts-ignore
+ const handleClosePress = () => ref.current?.close();
+
+ return (
+
+
+ Save Event
+
+ By saving this event, you are automatically signed up for
+ notifications and this event will be added to your calendar.
+
+
+
+
+
+
+ );
+});
+
+export default RSVPBottomSheet;
diff --git a/frontend/sac-mobile/app/(app)/tag/[id].tsx b/frontend/sac-mobile/app/(app)/tag/[id].tsx
new file mode 100644
index 000000000..426581a43
--- /dev/null
+++ b/frontend/sac-mobile/app/(app)/tag/[id].tsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import { Text, View } from 'react-native';
+
+const TagPage = () => {
+ return (
+
+ TagPage
+
+ );
+};
+
+export default TagPage;
diff --git a/frontend/sac-mobile/app/(auth)/_components/registration-form.tsx b/frontend/sac-mobile/app/(auth)/_components/registration-form.tsx
index 90f880692..a4c9b0861 100644
--- a/frontend/sac-mobile/app/(auth)/_components/registration-form.tsx
+++ b/frontend/sac-mobile/app/(auth)/_components/registration-form.tsx
@@ -168,6 +168,7 @@ const RegistrationForm = () => {
{
{
+import { Button } from '@/components/button';
+import { Wordmark } from '@/components/wordmark';
+
+const Layout = () => {
return (
{
options={{
title: '',
headerShown: true,
- animationTypeForReplace: 'push',
+ animationTypeForReplace: 'pop',
+ animation: 'slide_from_left',
statusBarColor: 'dark'
}}
/>
-
-
,
+ headerBackground: () => (
+
+ ),
+ animationTypeForReplace: 'push',
+ animation: 'slide_from_right'
+ }}
/>
,
+ headerRight: () => (
+
+ ),
+ headerBackground: () => (
+
+ ),
+ animationTypeForReplace: 'pop',
+ animation: 'slide_from_left'
+ }}
/>
+
+
);
};
-export default AuthLayout;
+export default Layout;
diff --git a/frontend/sac-mobile/app/(auth)/login.tsx b/frontend/sac-mobile/app/(auth)/login.tsx
index 8e106bab0..97d54aac2 100644
--- a/frontend/sac-mobile/app/(auth)/login.tsx
+++ b/frontend/sac-mobile/app/(auth)/login.tsx
@@ -1,20 +1,15 @@
import React from 'react';
-import { Text, View } from 'react-native';
+import { KeyboardAvoidingView, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
-import { Wordmark } from '@/components/wordmark';
-
import { LoginForm } from './_components/login-form';
const Login = () => {
return (
-
-
-
-
-
-
+
+
+
Let's go
@@ -35,7 +30,7 @@ const Login = () => {
-
+
);
};
diff --git a/frontend/sac-mobile/app/(auth)/register.tsx b/frontend/sac-mobile/app/(auth)/register.tsx
index db5ec52d5..da33237bf 100644
--- a/frontend/sac-mobile/app/(auth)/register.tsx
+++ b/frontend/sac-mobile/app/(auth)/register.tsx
@@ -1,43 +1,30 @@
import React from 'react';
-import { ScrollView, Text, View } from 'react-native';
+import { KeyboardAvoidingView, ScrollView, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
-import { router } from 'expo-router';
-
-import { Button } from '@/components/button';
-import { Wordmark } from '@/components/wordmark';
-
import { RegistrationForm } from './_components/registration-form';
const Register = () => {
return (
-
-
-
-
-
-
-
-
- Sign up
+
+
+
+
+
+ Sign up
+
+
+
+ Discover, follow, and join all the clubs & events
+ Northeastern has to offer
-
- Discover, follow, and join all the clubs & events
- Northeastern has to offer
-
-
-
-
-
-
+
+
+
+
+
);
};
diff --git a/frontend/sac-mobile/app/_layout.tsx b/frontend/sac-mobile/app/_layout.tsx
index 7b61e7db8..46b16131d 100644
--- a/frontend/sac-mobile/app/_layout.tsx
+++ b/frontend/sac-mobile/app/_layout.tsx
@@ -1,5 +1,6 @@
import { useEffect } from 'react';
import { View } from 'react-native';
+import { GestureHandlerRootView } from 'react-native-gesture-handler';
import Spinner from 'react-native-loading-spinner-overlay';
import { useFonts } from 'expo-font';
@@ -91,8 +92,10 @@ const RootLayout = () => {
return (
-
-
+
+
+
+
);
};
diff --git a/frontend/sac-mobile/babel.config.js b/frontend/sac-mobile/babel.config.js
index 0464179ed..94046263e 100644
--- a/frontend/sac-mobile/babel.config.js
+++ b/frontend/sac-mobile/babel.config.js
@@ -2,6 +2,6 @@ module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
- plugins: ['nativewind/babel']
+ plugins: ['nativewind/babel', 'react-native-reanimated/plugin']
};
};
diff --git a/frontend/sac-mobile/components/tag.tsx b/frontend/sac-mobile/components/tag.tsx
index faea441ad..455cc24a8 100644
--- a/frontend/sac-mobile/components/tag.tsx
+++ b/frontend/sac-mobile/components/tag.tsx
@@ -1,5 +1,7 @@
import { Text } from 'react-native';
+import { router } from 'expo-router';
+
import { Button } from '@/components/button';
import { Tag as T } from '@/types/tag';
@@ -10,7 +12,7 @@ type TagProps = {
const Tag = ({ tag }: TagProps) => {
return (
]