Skip to content

Commit

Permalink
Merge pull request #24 from simonyiszk/ui-improvements
Browse files Browse the repository at this point in the history
UI improvements
  • Loading branch information
berenteb authored Feb 3, 2024
2 parents a5fac85 + 4c84d02 commit ce59c69
Show file tree
Hide file tree
Showing 35 changed files with 308 additions and 200 deletions.
38 changes: 18 additions & 20 deletions app/(tabs)/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,39 @@
import React from 'react';
import { ScrollView, View } from 'react-native';

import { Screen } from '../../../components/base/screen';
import { ScrollContent } from '../../../components/base/scroll-content';
import { ErrorMessage } from '../../../components/common/error-message';
import { Header } from '../../../components/common/header';
import { SectionTitle } from '../../../components/common/sectiontitle';
import { Separator } from '../../../components/common/separator';
import { Title } from '../../../components/common/title';
import { HomeNewsList } from '../../../components/news/home-news-list';
import { HomePresentationList } from '../../../components/schedule/home-presentation-list';
import { PresentationItemSkeleton } from '../../../components/schedule/presentation-item-skeleton';
import { HomeNewsList } from '../../../components/news/layouts/home-news-list';
import { NewsItemSkeletonList } from '../../../components/news/layouts/news-item-skeleton-list';
import { HomePresentationList } from '../../../components/schedule/layouts/home-presentation-list';
import { PresentationItemSkeletonList } from '../../../components/schedule/layouts/presentation-item-skeleton-list';
import { useConference } from '../../../hooks/use-conference';
import { useNews } from '../../../hooks/use-news';

interface HomePageProps {}

export default function HomePage({}: HomePageProps) {
export default function HomePage() {
const conference = useConference();
const news = useNews();
return (
<Screen>
<Header>
<Title>Simonyi Konferencia</Title>
</Header>
<ScrollView className='px-5'>
<View className='mb-40'>
<SectionTitle>Előadások</SectionTitle>
{conference.isLoading && [0, 1].map((i) => <PresentationItemSkeleton key={i} />)}
{conference.isError && <ErrorMessage>Nem sikerült betölteni az előadásokat</ErrorMessage>}
{!conference.isError && !conference.isLoading && (
<HomePresentationList presentations={conference.data?.presentations ?? []} />
)}
<Separator />
<SectionTitle>Hírek</SectionTitle>
{news.data && <HomeNewsList news={news.data.news} />}
</View>
</ScrollView>
<ScrollContent>
<SectionTitle>Előadások</SectionTitle>
{conference.isLoading && <PresentationItemSkeletonList />}
{conference.isError && <ErrorMessage>Nem sikerült betölteni az előadásokat</ErrorMessage>}
{!conference.isError && !conference.isLoading && (
<HomePresentationList presentations={conference.data?.presentations ?? []} />
)}
<Separator />
<SectionTitle>Hírek</SectionTitle>
{news.isLoading && <NewsItemSkeletonList />}
{news.data && <HomeNewsList news={news.data.news} />}
</ScrollContent>
</Screen>
);
}
2 changes: 1 addition & 1 deletion app/(tabs)/home/news-details.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NewsDetailsPage } from '../../../components/news/news-details-page';
import { NewsDetailsPage } from '../../../components/news/layouts/news-details-page';
import { useSafeId } from '../../../utils/common.utils';

export default function NewsDetails() {
Expand Down
2 changes: 1 addition & 1 deletion app/(tabs)/home/presentation-details.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PresentationDetailsPage } from '../../../components/schedule/presentation-details-page';
import { PresentationDetailsPage } from '../../../components/schedule/layouts/presentation-details-page';
import { useSafeId } from '../../../utils/common.utils';

export default function PresentationDetails() {
Expand Down
4 changes: 1 addition & 3 deletions app/(tabs)/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { Header } from '../../components/common/header';
import { Title } from '../../components/common/title';
import { Map } from '../../components/map/map';

interface MapPageProps {}

export default function MapPage({}: MapPageProps) {
export default function MapPage() {
return (
<Screen>
<Header>
Expand Down
10 changes: 4 additions & 6 deletions app/(tabs)/presentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import { Screen } from '../../../components/base/screen';
import { ErrorMessage } from '../../../components/common/error-message';
import { Header } from '../../../components/common/header';
import { Title } from '../../../components/common/title';
import { PresentationItemSkeleton } from '../../../components/schedule/presentation-item-skeleton';
import { PresentationList } from '../../../components/schedule/presentation-list';
import { PresentationItemSkeletonList } from '../../../components/schedule/layouts/presentation-item-skeleton-list';
import { PresentationList } from '../../../components/schedule/layouts/presentation-list';
import { useConference } from '../../../hooks/use-conference';

interface PresentationListPageProps {}

export default function PresentationListPage({}: PresentationListPageProps) {
export default function PresentationListPage() {
const { data, isError, isLoading } = useConference();
return (
<Screen>
<Header>
<Title>Programterv</Title>
</Header>
{isLoading && [0, 1, 2, 3].map((i) => <PresentationItemSkeleton key={i} />)}
{isLoading && <PresentationItemSkeletonList />}
{!isError && !isLoading && <PresentationList presentations={data?.presentations ?? []} />}
{isError && <ErrorMessage>Nem sikerült betölteni az előadásokat</ErrorMessage>}
</Screen>
Expand Down
2 changes: 1 addition & 1 deletion app/(tabs)/presentation/presentation-details.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PresentationDetailsPage } from '../../../components/schedule/presentation-details-page';
import { PresentationDetailsPage } from '../../../components/schedule/layouts/presentation-details-page';
import { useSafeId } from '../../../utils/common.utils';

export default function ScheduleEventDetails() {
Expand Down
32 changes: 32 additions & 0 deletions components/base/item-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useState } from 'react';
import { GestureResponderEvent, Pressable, PressableProps } from 'react-native';

import { cn } from '../../utils/common.utils';

export function ItemCard({ className, onPressIn, onPressOut, ...props }: PressableProps) {
const [isPressed, setIsPressed] = useState(false);

const handlePressIn = (event: GestureResponderEvent) => {
setIsPressed(true);
onPressIn?.(event);
};

const handlePressOut = (event: GestureResponderEvent) => {
setIsPressed(false);
onPressOut?.(event);
};
return (
<Pressable
onPressIn={handlePressIn}
onPressOut={handlePressOut}
className={cn(
'mb-5 rounded-xl bg-white p-3 shadow-md shadow-slate-500/10 relative overflow-hidden',
{
'bg-slate-50': isPressed,
},
className
)}
{...props}
/>
);
}
14 changes: 9 additions & 5 deletions components/base/scroll-content.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { ScrollView, View, ViewProps } from 'react-native';
import { ScrollView, ScrollViewProps } from 'react-native';

import { cn } from '../../utils/common.utils';

export function ScrollContent({ className, ...props }: ViewProps) {
export function ScrollContent({ className, ...props }: ScrollViewProps) {
return (
<ScrollView>
<View className={cn('mx-5 pb-40', className)} {...props} />
</ScrollView>
<ScrollView
className={cn('px-5 pt-5', className)}
contentContainerStyle={{
paddingBottom: 130,
}}
{...props}
></ScrollView>
);
}
2 changes: 1 addition & 1 deletion components/common/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function Header({ children, className, ...props }: HeaderProps) {
const navigation = useNavigation();
const showBackButton = navigation.canGoBack();
return (
<View className={cn('space-y-5 mx-5 mb-5', className)} {...props}>
<View className={cn('space-y-5 mx-5', className)} {...props}>
{showBackButton && (
<Pressable onPress={navigation.goBack}>
<Feather name='arrow-left' size={30} color='#d45b7e' />
Expand Down
7 changes: 7 additions & 0 deletions components/common/item-highlight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { View, ViewProps } from 'react-native';

import { cn } from '../../utils/common.utils';

export function ItemHighlight({ className, ...props }: ViewProps) {
return <View className={cn('absolute top-0 right-0 bottom-0 w-1', className)} {...props} />;
}
10 changes: 10 additions & 0 deletions components/common/skeletons/skeleton-paragraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ViewProps } from 'react-native';

import { cn } from '../../../utils/common.utils';
import { SkeletonRectangle } from '../skeleton';

export function SkeletonParagraph({ className, ...props }: ViewProps) {
return Array.from({ length: 10 }).map((_, index) => (
<SkeletonRectangle key={index} className={cn('h-5 mb-2', className)} {...props} />
));
}
10 changes: 10 additions & 0 deletions components/common/skeletons/skeleton-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ViewProps } from 'react-native';

import { cn } from '../../../utils/common.utils';
import { SkeletonRectangle } from '../skeleton';

export function SkeletonTitle({ className, ...props }: ViewProps) {
return Array.from({ length: 2 }).map((_, index) => (
<SkeletonRectangle key={index} className={cn('h-10', className)} {...props} />
));
}
2 changes: 1 addition & 1 deletion components/common/subtitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StyledText } from '../base/text';

export function Subtitle({ children, className, ...props }: TextProps) {
return (
<StyledText className={cn('text-2xl text-slate-500', className)} {...props}>
<StyledText className={cn('text-2xl text-slate-500 mt-3', className)} {...props}>
{children}
</StyledText>
);
Expand Down
2 changes: 1 addition & 1 deletion components/common/title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StyledText } from '../base/text';

export function Title({ children, className, ...props }: TextProps) {
return (
<StyledText className={cn('text-4xl', className)} {...props}>
<StyledText className={cn('text-4xl mt-5', className)} {...props}>
{children}
</StyledText>
);
Expand Down
9 changes: 9 additions & 0 deletions components/news/elements/news-item-skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import { ViewProps } from 'react-native';

import { cn } from '../../../utils/common.utils';
import { SkeletonRectangle } from '../../common/skeleton';

export function NewsItemSkeleton({ className, ...props }: ViewProps) {
return <SkeletonRectangle className={cn('h-32 mb-5', className)} {...props} />;
}
37 changes: 37 additions & 0 deletions components/news/elements/news-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Feather } from '@expo/vector-icons';
import { useNavigation } from 'expo-router';
import { PressableProps, View } from 'react-native';
import { NativeStackNavigationProp } from 'react-native-screens/native-stack';

import { NewsItemDto } from '../../../types/news-api.type';
import { formatHu } from '../../../utils/date.utils';
import { ItemCard } from '../../base/item-card';
import { StyledText } from '../../base/text';

interface NewsItemProps extends Omit<PressableProps, 'onPress' | 'onPressIn' | 'onPressOut'> {
newsItem: NewsItemDto;
}

export function NewsItem({ newsItem, ...props }: NewsItemProps) {
const router = useNavigation<NativeStackNavigationProp<{ 'news-details': { id: string } }>>();
const onPress = () => {
router.navigate('news-details', { id: newsItem.url });
};
return (
<ItemCard className='space-y-2' onPress={onPress} {...props}>
{newsItem.highlighted && (
<View className='flex-row space-x-1 items-center'>
<Feather name='alert-circle' size={15} color='#ef4444' />
<StyledText className='text-red-500'>Kiemelt</StyledText>
</View>
)}
<StyledText className='text-xl' numberOfLines={2}>
{newsItem.title}
</StyledText>
<StyledText className='text-slate-500'>{formatHu(new Date(newsItem.timestamp))}</StyledText>
<StyledText className='text-slate-500' numberOfLines={2}>
{newsItem.briefContent}
</StyledText>
</ItemCard>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NewsItemDto } from '../../types/news-api.type';
import { StyledText } from '../base/text';
import { NewsItem } from './news-item';
import { NewsItemDto } from '../../../types/news-api.type';
import { StyledText } from '../../base/text';
import { NewsItem } from '../elements/news-item';

interface HomeNewsListProps {
news: NewsItemDto[];
Expand Down
33 changes: 33 additions & 0 deletions components/news/layouts/news-details-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useNewsItem } from '../../../hooks/use-news-item';
import { Screen } from '../../base/screen';
import { ScrollContent } from '../../base/scroll-content';
import { StyledText } from '../../base/text';
import { ErrorMessage } from '../../common/error-message';
import { Header } from '../../common/header';
import { SkeletonParagraph } from '../../common/skeletons/skeleton-paragraph';
import { SkeletonTitle } from '../../common/skeletons/skeleton-title';
import { Title } from '../../common/title';

interface NewsDetailsPageProps {
id: string;
}

export function NewsDetailsPage({ id }: NewsDetailsPageProps) {
const { data, error, isLoading } = useNewsItem(id);
if (!data) return <Screen />;
return (
<Screen>
<Header>
{isLoading && <SkeletonTitle />}
{data.title && <Title>{data.title}</Title>}
</Header>
<ScrollContent>
{error && (
<ErrorMessage>Hiba történt a hír betöltése közben. Lehet, hogy ez a hír nem is létezik?</ErrorMessage>
)}
{isLoading && <SkeletonParagraph />}
<StyledText className='text-xl'>{data?.content}</StyledText>
</ScrollContent>
</Screen>
);
}
5 changes: 5 additions & 0 deletions components/news/layouts/news-item-skeleton-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { NewsItemSkeleton } from '../elements/news-item-skeleton';

export function NewsItemSkeletonList() {
return Array.from({ length: 2 }, (_, i) => <NewsItemSkeleton key={i} />);
}
19 changes: 19 additions & 0 deletions components/news/layouts/news-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FlatList } from 'react-native';

import { NewsItemDto } from '../../../types/news-api.type';
import { NewsItem } from '../elements/news-item';

interface NewsListProps {
news: NewsItemDto[];
}

export function NewsList({ news }: NewsListProps) {
return (
<FlatList
contentContainerStyle={{ paddingBottom: 130 }}
data={news}
className='flex-grow px-5 pt-5'
renderItem={(listInfo) => <NewsItem newsItem={listInfo.item} />}
/>
);
}
28 changes: 0 additions & 28 deletions components/news/news-details-page.tsx

This file was deleted.

Loading

0 comments on commit ce59c69

Please sign in to comment.