First commit
This commit is contained in:
38
apk/components/birthdate-item.tsx
Normal file
38
apk/components/birthdate-item.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
// BirthdayItem.tsx
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
|
||||
interface BirthdayItemProps {
|
||||
name: string;
|
||||
date: string;
|
||||
age?: number;
|
||||
}
|
||||
|
||||
export function BirthdayItem({ name, date, age }: BirthdayItemProps) {
|
||||
return (
|
||||
<View style={styles.itemContainer}>
|
||||
<Text style={styles.name}>{name}</Text>
|
||||
{age && <Text style={styles.age}>Age: {age}</Text>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
itemContainer: {
|
||||
padding: 15,
|
||||
borderRadius: 8,
|
||||
backgroundColor: "#f0f0f0",
|
||||
boxShadow: "0 1px 4px rgba(0,0,0,0.3)",
|
||||
marginBottom: 10,
|
||||
},
|
||||
name: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
date: {
|
||||
fontSize: 14,
|
||||
},
|
||||
age: {
|
||||
fontSize: 12,
|
||||
marginTop: 5,
|
||||
},
|
||||
});
|
||||
127
apk/components/birthdate-list.tsx
Normal file
127
apk/components/birthdate-list.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
// birthdate-list.tsx
|
||||
import { useRouter } from "expo-router";
|
||||
import {
|
||||
SectionList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { BirthdayItem } from "./birthdate-item";
|
||||
|
||||
const DATA = [
|
||||
{ id: "1", name: "John Doe", date: "2024-01-15" },
|
||||
{ id: "2", name: "Jane Smith", date: "2024-01-15" },
|
||||
{ id: "3", name: "Bob Johnson", date: "2024-02-10" },
|
||||
{ id: "4", name: "Alice Brown", date: "2024-02-10" },
|
||||
{ id: "5", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
{ id: "6", name: "Bob Johnson", date: "2024-02-10" },
|
||||
{ id: "7", name: "Alice Brown", date: "2024-02-10" },
|
||||
{ id: "8", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
{ id: "9", name: "Bob Johnson", date: "2024-02-10" },
|
||||
{ id: "10", name: "Alice Brown", date: "2024-02-10" },
|
||||
{ id: "11", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
{ id: "12", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
{ id: "13", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
{ id: "14", name: "Charlie Wilson", date: "2024-01-20" },
|
||||
];
|
||||
|
||||
interface BirthdayItemData {
|
||||
id: string;
|
||||
name: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
interface SectionData {
|
||||
title: string;
|
||||
data: BirthdayItemData[];
|
||||
}
|
||||
|
||||
export function BirthdayList() {
|
||||
const router = useRouter();
|
||||
const groupedData = groupBirthdaysByDate(DATA);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={{ fontSize: 24, fontWeight: "bold" }}>
|
||||
Upcoming Birthdays
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress={() => router.push("/add")}
|
||||
style={styles.addButton}
|
||||
>
|
||||
<Text style={styles.addButtonText}>+</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<SectionList
|
||||
sections={groupedData}
|
||||
keyExtractor={(item) => item.id}
|
||||
renderItem={({ item }) => (
|
||||
<BirthdayItem name={item.name} date={item.date} />
|
||||
)}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderSectionHeader={({ section: { title } }) => (
|
||||
<View style={styles.headerContainer}>
|
||||
<Text style={styles.sectionHeader}>{title}</Text>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to group and sort
|
||||
function groupBirthdaysByDate(data: BirthdayItemData[]): SectionData[] {
|
||||
// Sort by date
|
||||
const sorted = [...data].sort((a, b) => {
|
||||
return new Date(a.date).getTime() - new Date(b.date).getTime();
|
||||
});
|
||||
|
||||
// Group by date
|
||||
const grouped = sorted.reduce((acc, item) => {
|
||||
const existing = acc.find((section) => section.title === item.date);
|
||||
|
||||
if (existing) {
|
||||
existing.data.push(item);
|
||||
} else {
|
||||
acc.push({ title: item.date, data: [item] });
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as SectionData[]);
|
||||
|
||||
return grouped;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
titleContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 10,
|
||||
},
|
||||
addButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "#007AFF",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
addButtonText: {
|
||||
fontSize: 24,
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
headerContainer: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 5,
|
||||
},
|
||||
sectionHeader: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
});
|
||||
44
apk/components/scroll-view.tsx
Normal file
44
apk/components/scroll-view.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
import Animated, { useAnimatedRef } from "react-native-reanimated";
|
||||
|
||||
import { useColorScheme } from "@/hooks/use-color-scheme";
|
||||
import { useThemeColor } from "@/hooks/use-theme-color";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { View } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
type Props = PropsWithChildren<{
|
||||
headerBackgroundColor: { dark: string; light: string };
|
||||
}>;
|
||||
|
||||
export default function ScrollView({ children, headerBackgroundColor }: Props) {
|
||||
const scrollRef = useAnimatedRef<Animated.ScrollView>();
|
||||
const insets = useSafeAreaInsets();
|
||||
const colorScheme = useColorScheme() ?? "light";
|
||||
const backgroundColor = useThemeColor({}, "background");
|
||||
|
||||
return (
|
||||
<View
|
||||
ref={scrollRef}
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
backgroundColor,
|
||||
paddingTop: insets.top,
|
||||
},
|
||||
]}
|
||||
scrollEventThrottle={16}
|
||||
>
|
||||
<View style={styles.content}>{children}</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#ccc",
|
||||
},
|
||||
|
||||
content: {},
|
||||
});
|
||||
Reference in New Issue
Block a user