frontend-app/app/HomeScreen.tsx
2025-09-30 15:29:12 +02:00

160 lines
3.7 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { Linking, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Item } from 'types/Item';
const API_URL = "http://192.168.178.22:8000";
export default function HomeScreen() {
const [data, setData] = useState<Item[]>([]);
const [selected, setSelected] = useState<'home' | 'royal-road' | 'podcasts' | 'mixtapes'>('home');
const [menuOpen, setMenuOpen] = useState(false);
useEffect(() => {
fetch(API_URL)
.then(res => res.json())
.then(json => {
if (json.status === "ok" && Array.isArray(json.data)) {
setData(json.data);
}
})
.catch(err => console.error("API error:", err));
}, []);
// Filter items for current category
const filteredData =
selected === "home" ? data : data.filter(item => item.category === selected);
const menuItems = [
{ label: 'Home', key: 'home' },
{ label: 'Royal Road', key: 'royal-road' },
{ label: 'Podcasts', key: 'podcasts' },
{ label: 'Mixtapes', key: 'mixtapes' },
];
return (
<SafeAreaView style={styles.container}>
{/* Side Menu */}
<View style={[styles.sideMenu, menuOpen && styles.sideMenuOpen]}>
{menuItems.map(item => (
<TouchableOpacity
key={item.key}
style={[styles.menuItem, selected === item.key && styles.menuItemSelected]}
onPress={() => {
setSelected(item.key as any);
setMenuOpen(false);
}}
>
<Text style={styles.menuText}>{item.label}</Text>
</TouchableOpacity>
))}
</View>
{/* Main Content */}
<View style={styles.mainContent}>
<TouchableOpacity style={styles.menuButton} onPress={() => setMenuOpen(!menuOpen)}>
<Text style={styles.menuButtonText}></Text>
</TouchableOpacity>
<Text style={styles.title}>
{selected === 'home' && 'Welcome to Home!'}
{selected === 'royal-road' && 'Royal Road Updates'}
{selected === 'podcasts' && 'Latest Podcasts'}
{selected === 'mixtapes' && 'New Mixtapes'}
</Text>
<ScrollView style={styles.dataContainer}>
{filteredData.map(item => (
<View key={item.timestamp + item.title} style={styles.dataItem}>
<Text style={styles.dataTitle}>{item.title}</Text>
<Text style={styles.dataDescription}>{item.info}</Text>
<TouchableOpacity onPress={() => Linking.openURL(item.link)}>
<Text style={{ color: "blue" }}>Read more</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
backgroundColor: '#f2f2f2',
},
sideMenu: {
width: 0,
backgroundColor: '#333',
paddingTop: 40,
paddingHorizontal: 0,
overflow: 'hidden',
},
sideMenuOpen: {
width: 180,
paddingHorizontal: 16,
},
menuItem: {
paddingVertical: 16,
paddingHorizontal: 8,
borderRadius: 4,
marginBottom: 8,
},
menuItemSelected: {
backgroundColor: '#555',
},
menuText: {
color: '#fff',
fontSize: 18,
},
mainContent: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
},
menuButton: {
position: 'absolute',
top: 40,
left: 16,
zIndex: 1,
backgroundColor: '#333',
borderRadius: 20,
padding: 8,
},
menuButtonText: {
color: '#fff',
fontSize: 24,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginTop: 60,
color: '#333',
},
dataContainer: {
marginTop: 24,
width: '90%',
},
dataItem: {
backgroundColor: '#fff',
borderRadius: 8,
padding: 16,
marginBottom: 12,
shadowColor: '#000',
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2,
},
dataTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#222',
marginBottom: 4,
},
dataDescription: {
fontSize: 15,
color: '#555',
},
});