diff --git a/eas.json b/eas.json index 05968b2..7190d87 100644 --- a/eas.json +++ b/eas.json @@ -3,8 +3,8 @@ "preview": { "distribution": "internal", "env": { - "EXPO_PUBLIC_EVENT_API_URL": "https://neuf.no/api/v1/events/", - "EXPO_PUBLIC_DUSKEN_API_URL": "https://galtinn.neuf.no/", + "EXPO_PUBLIC_EVENT_API_URL": "https://neuf.no/api/v1/events", + "EXPO_PUBLIC_DUSKEN_API_URL": "https://galtinn.neuf.no", "EXPO_PUBLIC_DUSKEN_FORGOT_PASSWORD_URL": "https://galtinn.neuf.no/auth/password_reset/", "EXPO_PUBLIC_DUSKEN_PRIVACY_POLICY_URL": "https://galtinn.neuf.no/nb/personvern/", "EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY": "pk_test_4SNAIZZczSJKZ0y2wrZI4Ngb" @@ -12,8 +12,8 @@ }, "production": { "env": { - "EXPO_PUBLIC_EVENT_API_URL": "https://neuf.no/api/v1/events/", - "EXPO_PUBLIC_DUSKEN_API_URL": "https://galtinn.neuf.no/", + "EXPO_PUBLIC_EVENT_API_URL": "https://neuf.no/api/v1/events", + "EXPO_PUBLIC_DUSKEN_API_URL": "https://galtinn.neuf.no", "EXPO_PUBLIC_DUSKEN_FORGOT_PASSWORD_URL": "https://galtinn.neuf.no/auth/password_reset/", "EXPO_PUBLIC_DUSKEN_PRIVACY_POLICY_URL": "https://galtinn.neuf.no/nb/personvern/", "EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY": "pk_live_4SNAG73lw9kqFGb5u1s0yHhA", diff --git a/env-example b/env-example index eef2fb3..3d5368e 100644 --- a/env-example +++ b/env-example @@ -1,5 +1,5 @@ -EXPO_PUBLIC_EVENT_API_URL=https://neuf.no/api/v1/events/ -EXPO_PUBLIC_DUSKEN_API_URL=https://galtinn.neuf.no/ +EXPO_PUBLIC_EVENT_API_URL=https://neuf.no/api/v1/events +EXPO_PUBLIC_DUSKEN_API_URL=https://galtinn.neuf.no EXPO_PUBLIC_DUSKEN_FORGOT_PASSWORD_URL=https://galtinn.neuf.no/auth/password_reset/ EXPO_PUBLIC_DUSKEN_PRIVACY_POLICY_URL=https://galtinn.neuf.no/nb/personvern/ EXPO_PUBLIC_SENTRY_DSN= diff --git a/package-lock.json b/package-lock.json index 407dbeb..349462c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cnapp", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cnapp", - "version": "2.0.0", + "version": "2.0.1", "dependencies": { "@apollo/client": "^3.10.8", "@babel/plugin-transform-private-methods": "^7.24.7", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index c0763ce..0a6a375 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -7,7 +7,6 @@ import IconEvent from 'assets/icons/event.svg'; import IconInfo from 'assets/icons/information-circle.svg'; import IconPerson from 'assets/icons/person.svg'; import About from 'src/modules/about/About'; -import EventDetail from 'src/modules/events/EventDetail'; import EventList from 'src/modules/events/EventList'; import Login from 'src/modules/login/Login'; import Membership from 'src/modules/membership/Membership'; @@ -37,17 +36,6 @@ const EventStackScreen = () => ( title: 'Program', }} /> - ({ - // TODO: make this not suck - title: - route.params.event.title.decoded.length < 40 - ? route.params.event.title.decoded - : `${route.params.event.title.decoded.substring(0, 30)}...`, - })} - /> ); diff --git a/src/components/FormInput.tsx b/src/components/FormInput.tsx index 35f7572..a49e2f7 100644 --- a/src/components/FormInput.tsx +++ b/src/components/FormInput.tsx @@ -58,6 +58,7 @@ const styles = StyleSheet.create({ borderColor: theme.colors.neufPurple, borderWidth: 1, borderRadius: 4, + backgroundColor: 'white', padding: 4, marginVertical: 4, }, diff --git a/src/modules/events/EventList.tsx b/src/modules/events/EventList.tsx index 8d9e4ec..af851cb 100644 --- a/src/modules/events/EventList.tsx +++ b/src/modules/events/EventList.tsx @@ -1,16 +1,7 @@ import { SimpleLineIcons as Icon } from '@expo/vector-icons'; import moment from 'moment'; import React from 'react'; -import { - StyleSheet, - View, - Platform, - SectionList, - TouchableOpacity, - ActivityIndicator, - Text, - Linking, -} from 'react-native'; +import { StyleSheet, View, Platform, FlatList, TouchableOpacity, Text, Linking } from 'react-native'; import { Button } from 'react-native-ui-lib'; import 'moment/locale/nb'; @@ -25,29 +16,37 @@ const formatTime = (time: string) => { return moment(time).format('llll'); }; -const renderSectionHeader = ({ section }: { section: { title: string } }) => ( - - {section.title} - -); const Header = () => ; const EventList = () => { - const { eventsSectioned, refreshing, handleRefresh, handleLoadMore, error, loading } = useEventList(); + const { events, refreshing, handleRefresh, error } = useEventList(); - const renderItem = ({ item }: { item: EventType }) => ( + const renderItem = ({ item, index }: { item: EventType; index: number }) => ( { - return Linking.openURL(items.url); + return Linking.openURL(item.url); }} - style={styles.listItem} + style={[styles.listItem, ...(index === (events.length -1) ? [styles.lastListItem] : [])]} > {item.title} - {formatTime(item.nextOccurence.start)} + {item.subtitle && ( + + {item.subtitle} + + )} + + {item.futureOccurrencesCount > 1 && 'Neste: '} + {formatTime(item.nextOccurrence.start)} + {item.nextOccurrence.venue && + ` ${item.nextOccurrence.venue.preposition} ${item.nextOccurrence.venue.title}`} + + {item.futureOccurrencesCount > 1 && ( + {`Se flere tider (${item.futureOccurrencesCount - 1})`} + )} @@ -56,15 +55,6 @@ const EventList = () => { ); - // FIXME: Hoist component definition - // eslint-disable-next-line react/no-unstable-nested-components - const Footer = () => - !loading && ( - - - - ); - if (error) { return ( @@ -81,17 +71,12 @@ const EventList = () => { } return ( - item.id} refreshing={refreshing} onRefresh={handleRefresh} - onEndReached={handleLoadMore} - onEndReachedThreshold={10} - initialNumToRender={10} - ListFooterComponent={Footer} style={[theme.card, styles.list]} ListHeaderComponent={Header} /> @@ -101,16 +86,23 @@ export default EventList; const styles = StyleSheet.create({ listItem: { - backgroundColor: theme.colors.neufWhite, + backgroundColor: theme.colors.betongGray, paddingTop: 10, paddingBottom: 12, paddingLeft: 12, paddingRight: 12, borderBottomWidth: 1, - borderBottomColor: theme.colors.neufGray, + borderBottomColor: theme.colors.neufPink, + }, + lastListItem: { + borderBottomWidth: 0, }, listItemTitle: { fontSize: 16, + fontWeight: 'bold', + }, + listItemSubtitle: { + fontSize: 16, }, listItemTime: { fontSize: 14, @@ -140,6 +132,7 @@ const styles = StyleSheet.create({ }, listHeader: { paddingTop: 8, + backgroundColor: theme.colors.neufGray, }, arrow: { flex: 1, diff --git a/src/modules/events/useEventList.tsx b/src/modules/events/useEventList.tsx index eeb7cc3..a9236ed 100644 --- a/src/modules/events/useEventList.tsx +++ b/src/modules/events/useEventList.tsx @@ -22,39 +22,11 @@ const useEventList = () => { const [loading, setLoading] = useState(false); const [events, setEvents] = useState([]); - const [eventsSectioned, setEventsSectioned] = useState([]); - const [page, setPage] = useState(1); - const [totalPages, setTotalPages] = useState(0); const [error, setError] = useState(null); const [refreshing, setRefreshing] = useState(false); - const toSectionFormat = (freshEvents: EventType[]) => { - const sectioned: Record = {}; - freshEvents.forEach((event) => { - const title = formatDate(event.start_time); - if (title in sectioned) { - sectioned[title].push(event); - } else { - sectioned[title] = [event]; - } - }); - - return Object.entries(sectioned).map(([title, section]) => ({ data: section, title })); - }; - const handleRefresh = () => { - setPage(1); setRefreshing(true); - setTotalPages(1); - fetchEvents(); - }; - - const handleLoadMore = () => { - if (page >= totalPages || loading) { - return; - } - - setPage(page + 1); fetchEvents(); }; @@ -62,19 +34,19 @@ const useEventList = () => { const url = `${process.env.EXPO_PUBLIC_EVENT_API_URL}?view=compact-app`; setLoading(true); - let eventData; + let response; + let events; try { const res = await fetchWithTimeout(url); - eventData = await res.json().events; + response = await res.json(); + events = response.events; } catch (err) { setError(err); setLoading(false); return; } - setTotalPages(Math.floor(eventData.total / 10)); - setEvents(page === 1 ? eventData : [...events, ...eventData]); - setEventsSectioned(page === 1 ? toSectionFormat(eventData) : toSectionFormat([...events, ...eventData])); - setError(eventData.error || null); + setEvents(events); + setError(response.error || null); setLoading(false); setRefreshing(false); }; @@ -86,10 +58,8 @@ const useEventList = () => { return { handleRefresh, - handleLoadMore, error, events, - eventsSectioned, refreshing, loading, }; diff --git a/src/modules/membership/UserDelete.tsx b/src/modules/membership/UserDelete.tsx index 624c3b6..e572c63 100644 --- a/src/modules/membership/UserDelete.tsx +++ b/src/modules/membership/UserDelete.tsx @@ -92,6 +92,7 @@ const styles = StyleSheet.create({ input: { height: 40, borderColor: theme.colors.neufPurple, + backgroundColor: 'white', borderWidth: 1, margin: 10, padding: 10, diff --git a/src/theme.ts b/src/theme.ts index a957162..91f8d22 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -6,7 +6,6 @@ const colors = { success: '#5cb85c', lightText: '#666', neufPurple: '#720328', - neufPink: '#CD96AB', neufGray: '#E5E2D7', neufOrange: '#f58220', neufBeige: '#F8BC90', @@ -14,6 +13,13 @@ const colors = { neufWhite: '#FFFFFF', neufBlack: '#161516', gray1: '#dddddd', + // 2024 colors + deepBrick: '#720328', + neufPink: '#cd96ab', + betongGray: '#e5e2d7', + goldenOrange: '#ff6915', + goldenBeige: '#f8bc90', + chateauBlue: '#0a0f6d', }; const card = { diff --git a/src/types/data.ts b/src/types/data.ts index 7f8381c..71ebfa0 100644 --- a/src/types/data.ts +++ b/src/types/data.ts @@ -1,21 +1,25 @@ +export interface Venue { + id: string; + slug: string; + title: string; + preposition: string; + url: string; +} + +export interface EventOccurrence { + id: string; + start: string; + end?: string; + venue: Venue; +} + export interface EventType { id: string; - start_time: string; - end_time: string; - content: { - rendered: string; - }; - venue: string; - title: { - decoded: string; - }; - thumbnail: { - medium_large: string; - }; - price_regular: string; - price_member: string; - ticket_url: string; - facebook_url: string; + title: string; + subtitle?: string; + url: string; + nextOccurrence: EventOccurrence; + futureOccurrencesCount: number; } export interface MembershipType { diff --git a/src/types/navigation.ts b/src/types/navigation.ts index 30aab5a..8d801ba 100644 --- a/src/types/navigation.ts +++ b/src/types/navigation.ts @@ -8,8 +8,6 @@ export type EventStackParamList = { EventDetail: { event: EventType }; }; -export type EventDetailProps = NativeStackScreenProps; - export type UserStackParamList = { Membership: undefined; Login: undefined;