Skip to content

Commit

Permalink
Sessionize data, schedule, session page and zustand store
Browse files Browse the repository at this point in the history
  • Loading branch information
kharioki committed Sep 24, 2024
1 parent 43f04a6 commit 286b435
Show file tree
Hide file tree
Showing 25 changed files with 1,193 additions and 197 deletions.
6 changes: 6 additions & 0 deletions app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export default function TabLayout() {
headerShown: false,
}}
/>
<Stack.Screen
name="sessions"
options={{
headerShown: false,
}}
/>
</Stack>
);
}
79 changes: 67 additions & 12 deletions app/(tabs)/home/bookmarks.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,83 @@
import { StyleSheet, View } from 'react-native';
import { FlatList, StyleSheet, View } from 'react-native';
import MainContainer from '@/components/containers/MainContainer';
import StyledText from '@/components/common/StyledText';
import { spacing } from '@/constants/Styles';
// import Colors from '@/constants/Colors';
import { sizes, spacing } from '@/constants/Styles';
import { useBookmarkStore } from '@/state/bookmarks';
import { useStore } from '@/state/store';
import Colors from '@/constants/Colors';
import { getSpeaker, getRoom } from '@/utils/sessions';
import SessionCard from '@/components/cards/SessionCard';
import { useRouter } from 'expo-router';

export default function BookmarksPage() {
const router = useRouter();

const bookmarks = useBookmarkStore((state) => state.bookmarks);
const allSessions = useStore((state) => state.allSessions);
const sessions = useStore((state) => state.allSessions.sessions);
const bookmarkedSessions = sessions.filter((session) =>
bookmarks.some((bookmark) => bookmark.sessionId === session.id),
);

const home = () => {
return (
<MainContainer backgroundImage={require('@/assets/images/bg.png')} ImageBackgroundProps={{ resizeMode: 'cover' }}>
<MainContainer
backgroundImage={require('@/assets/images/bg.png')}
ImageBackgroundProps={{ resizeMode: 'cover' }}
preset="scroll"
safeAreaEdges={['top']}
>
<View style={styles.container}>
<StyledText size="lg" font="semiBold">
Bookmarks
<StyledText size="xl" font="semiBold" style={styles.header}>
Bookmarked Sessions
</StyledText>

<FlatList
data={bookmarkedSessions}
renderItem={({ item }) => {
const speakers = item.speakers.map((speakerId) => getSpeaker(speakerId, allSessions));
return (
<SessionCard
session={{ ...item, room: 'TBA' }}
speakers={speakers}
room={item?.roomId ? getRoom(item.roomId, allSessions).name : 'TBA'}
onPress={() => router.push(`/sessions/${item.id}`)}
/>
);
}}
keyExtractor={(item) => item.id}
initialNumToRender={10}
maxToRenderPerBatch={10}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ height: sizes.md }} />}
ListEmptyComponent={
<StyledText size="base" style={styles.error}>
No bookmarked sessions found.
</StyledText>
}
scrollEnabled={false}
/>
</View>
</MainContainer>
);
};

export default home;
}

const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: spacing.lg,
paddingTop: sizes.header,
paddingHorizontal: sizes.md,
paddingBottom: sizes.xxxl,
width: '100%',
paddingBottom: spacing.xl,
},
header: {
color: Colors.palette.secondary,
marginVertical: sizes.xl,
},
sessions: {
// flex: 1,
gap: spacing.md,
},
error: {
textAlign: 'center',
},
});
94 changes: 82 additions & 12 deletions app/(tabs)/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,97 @@
import { StyleSheet, View } from 'react-native';
import { FlatList, StyleSheet, View } from 'react-native';
import MainContainer from '@/components/containers/MainContainer';
import StyledText from '@/components/common/StyledText';
import { spacing } from '@/constants/Styles';
// import Colors from '@/constants/Colors';
import { sizes, spacing } from '@/constants/Styles';
import Colors from '@/constants/Colors';
import { useStore } from '@/state/store';
import { useRouter } from 'expo-router';
import SessionCard from '@/components/cards/SessionCard';
import { getRoom, getSpeaker } from '@/utils/sessions';
import ListHeaderButton from '@/components/headers/ListHeaderButton';
import { format } from 'date-fns';

export default function Schedule() {
const router = useRouter();
const allSessions = useStore((state) => state.allSessions);
const sessions = useStore((state) => state.allSessions.sessions);

const home = () => {
return (
<MainContainer backgroundImage={require('@/assets/images/bg.png')} ImageBackgroundProps={{ resizeMode: 'cover' }}>
<MainContainer
backgroundImage={require('@/assets/images/bg.png')}
ImageBackgroundProps={{ resizeMode: 'cover' }}
preset="scroll"
safeAreaEdges={['top']}
>
<View style={styles.container}>
<StyledText size="lg" font="semiBold">
Schedule page
</StyledText>
<FlatList
data={sessions}
ListHeaderComponent={() => {
return (
<View style={[styles.sectionHeader]}>
<ListHeaderButton
title={format('2024-10-04T00:00:00Z', 'EEE')}
subtitle="Day 1"
isBold={true}
onPress={() => {}}
/>
<ListHeaderButton
title={format('2024-10-05T00:00:00Z', 'EEE')}
subtitle="Day 2"
isBold={false}
onPress={() => {}}
/>
</View>
);
}}
renderItem={({ item }) => {
const speakers = item.speakers.map((speakerId) => getSpeaker(speakerId, allSessions));
return (
<SessionCard
session={{ ...item, room: '' }}
speakers={speakers}
room={item?.roomId ? getRoom(item.roomId, allSessions).name : 'TBA'}
onPress={() => router.push(`/sessions/${item.id}`)}
/>
);
}}
keyExtractor={(item) => item.id}
initialNumToRender={10}
maxToRenderPerBatch={10}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ height: sizes.md }} />}
ListEmptyComponent={
<StyledText size="base" style={styles.error}>
No sessions found.
</StyledText>
}
scrollEnabled={false}
/>
</View>
</MainContainer>
);
};

export default home;
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: spacing.lg,
paddingTop: sizes.header + 40,
paddingHorizontal: sizes.md,
paddingBottom: sizes.xxxl,
width: '100%',
},
header: {
color: Colors.palette.secondary,
marginVertical: sizes.md,
},
sectionHeader: {
marginBottom: sizes.md,
paddingHorizontal: spacing.lg,
paddingVertical: spacing.md,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
error: {
textAlign: 'center',
},
});
34 changes: 13 additions & 21 deletions app/(tabs)/home/speakers.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { FlatList, View, ActivityIndicator, StyleSheet } from 'react-native';
import { FlatList, View, StyleSheet } from 'react-native';
import Colors from '@/constants/Colors';
import SpeakerCard from '@/components/cards/SpeakerCard';
import { useFetchSpeakers } from '@/hooks/useFetchSpeakers';
import StyledText from '@/components/common/StyledText';
import MainContainer from '@/components/containers/MainContainer';
import { sizes } from '@/constants/Styles';
import { useRouter } from 'expo-router';
import { useStore } from '@/state/store';

const Speakers = () => {
const router = useRouter();
const { speakerList, loading, error } = useFetchSpeakers();
const speakers = useStore((state) => state.allSessions.speakers);

return (
<MainContainer
Expand All @@ -22,24 +22,16 @@ const Speakers = () => {
<StyledText size="xl" font="semiBold" style={styles.header}>
Speakers
</StyledText>
{loading ? (
<ActivityIndicator size="large" color={Colors.palette.secondary} />
) : error ? (
<StyledText variant="error" style={styles.error}>
Failed to load speakers. Please try again later.
</StyledText>
) : (
<FlatList
data={speakerList}
renderItem={({ item }) => (
<SpeakerCard speaker={item} onPress={() => router.push(`/speakers/${item.id}`)} />
)}
keyExtractor={(item) => item.id}
initialNumToRender={10}
maxToRenderPerBatch={10}
showsVerticalScrollIndicator={false}
/>
)}
<FlatList
data={speakers}
renderItem={({ item }) => <SpeakerCard speaker={item} onPress={() => router.push(`/speakers/${item.id}`)} />}
keyExtractor={(item) => item.id}
initialNumToRender={10}
maxToRenderPerBatch={10}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ height: sizes.md }} />}
ListEmptyComponent={<StyledText style={styles.error}>No speakers found. Please try again later.</StyledText>}
/>
</View>
</MainContainer>
);
Expand Down
Loading

0 comments on commit 286b435

Please sign in to comment.