Skip to content

Commit 503146d

Browse files
committed
added quote presets to display on notifications tab
1 parent cfacc29 commit 503146d

2 files changed

Lines changed: 148 additions & 44 deletions

File tree

KonditionExpo/app/notification.tsx

Lines changed: 110 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,128 @@
1-
import React from 'react';
2-
import { View, Text, StyleSheet, TouchableOpacity, FlatList, Image } from 'react-native';
3-
/*
4-
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
5-
6-
const notifications = [
7-
{ id: '1', title: "Hey, it's time for lunch", time: 'About 1 minute ago', icon: require('./assets/lunch.png') },
8-
{ id: '2', title: "Don't miss your lowerbody workout", time: 'About 3 hours ago', icon: require('./assets/workout.png') },
9-
{ id: '3', title: "Hey, let's add some meals for your b..", time: 'About 3 hours ago', icon: require('./assets/meals.png') },
10-
{ id: '4', title: 'Congratulations, You have finished A..', time: '29 May', icon: require('./assets/congrats.png') },
11-
{ id: '5', title: "Hey, it's time for lunch", time: '8 April', icon: require('./assets/lunch.png') },
12-
{ id: '6', title: 'Ups, You have missed your Lowerbo..', time: '3 April', icon: require('./assets/workout.png') },
13-
];
14-
*/
15-
16-
export default function NotificationScreen({ navigation }) {
17-
const renderItem = ({ item }) => (
1+
// app/screens/NotificationScreen.tsx
2+
3+
import React, { useState, useEffect } from "react";
4+
import {
5+
SafeAreaView,
6+
View,
7+
Text,
8+
StyleSheet,
9+
FlatList,
10+
Dimensions,
11+
ActivityIndicator,
12+
} from "react-native";
13+
14+
// Define the shape of each quote, matching QuoteOut from the backend
15+
type QuoteItem = {
16+
date: string; // "YYYY-MM-DD"
17+
text: string;
18+
};
19+
20+
export default function NotificationScreen() {
21+
const [notifications, setNotifications] = useState<QuoteItem[]>([]);
22+
const [loading, setLoading] = useState(true);
23+
24+
useEffect(() => {
25+
// Fetch the last 7 days of quotes from the backend
26+
// Replace localhost with your actual host or LAN IP if testing on device
27+
fetch("http://localhost:8000/api/v1/notifications/quotes")
28+
.then((res) => res.json())
29+
.then((data: QuoteItem[]) => {
30+
// data is an array like [{ date: "2025-06-05", text: "..." }, …]
31+
setNotifications(data);
32+
})
33+
.catch((err) => {
34+
console.error("Error fetching quotes:", err);
35+
})
36+
.finally(() => {
37+
setLoading(false);
38+
});
39+
}, []);
40+
41+
const renderItem = ({ item }: { item: QuoteItem }) => (
1842
<View style={styles.item}>
19-
<Image source={item.icon} style={styles.itemIcon} />
2043
<View style={styles.itemText}>
21-
<Text style={styles.title} numberOfLines={1}>{item.title}</Text>
22-
<Text style={styles.time}>{item.time}</Text>
44+
<Text style={styles.title} numberOfLines={2}>
45+
{item.text}
46+
</Text>
47+
<Text style={styles.time}>{item.date}</Text>
2348
</View>
24-
<TouchableOpacity style={styles.itemMenu}>
25-
<Icon name="dots-vertical" size={20} />
26-
</TouchableOpacity>
2749
</View>
2850
);
51+
52+
if (loading) {
53+
return (
54+
<SafeAreaView style={styles.container}>
55+
<ActivityIndicator size="large" color="#333" />
56+
</SafeAreaView>
57+
);
58+
}
59+
2960
return (
30-
<View style={styles.container}>
61+
<SafeAreaView style={styles.container}>
3162
<View style={styles.header}>
32-
<TouchableOpacity onPress={() => navigation.goBack()}>
33-
<Icon name="arrow-left" size={24} />
34-
</TouchableOpacity>
35-
<Text style={styles.headerTitle}>Notification</Text>
36-
<TouchableOpacity>
37-
<Icon name="dots-horizontal" size={24} />
38-
</TouchableOpacity>
63+
<Text style={styles.headerTitle}>Daily Quotes</Text>
3964
</View>
4065
<FlatList
4166
data={notifications}
42-
keyExtractor={item => item.id}
67+
keyExtractor={(item) => item.date}
4368
renderItem={renderItem}
4469
ItemSeparatorComponent={() => <View style={styles.separator} />}
70+
contentContainerStyle={styles.listContent}
4571
/>
46-
</View>
72+
</SafeAreaView>
4773
);
4874
}
4975

76+
const { width, height } = Dimensions.get("window");
77+
5078
const styles = StyleSheet.create({
51-
container: { flex: 1, backgroundColor: '#fff' },
52-
header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', padding: 16 },
53-
headerTitle: { fontSize: 18, fontWeight: 'bold' },
54-
item: { flexDirection: 'row', alignItems: 'center', padding: 16 },
55-
itemIcon: { width: 40, height: 40, borderRadius: 20 },
56-
itemText: { flex: 1, marginLeft: 12 },
57-
title: { fontSize: 16 },
58-
time: { fontSize: 12, color: '#888' },
59-
itemMenu: { padding: 8 },
60-
separator: { height: 1, backgroundColor: '#eee', marginLeft: 68 },
79+
container: {
80+
flex: 1,
81+
width,
82+
height,
83+
backgroundColor: "#ffffff",
84+
alignItems: "center",
85+
justifyContent: "center",
86+
},
87+
header: {
88+
padding: 16,
89+
borderBottomWidth: 1,
90+
borderBottomColor: "#ddd",
91+
backgroundColor: "#fafafa",
92+
alignItems: "center",
93+
width: "100%",
94+
},
95+
headerTitle: {
96+
fontSize: 20,
97+
fontWeight: "bold",
98+
},
99+
listContent: {
100+
paddingVertical: 8,
101+
width: "100%",
102+
},
103+
item: {
104+
flexDirection: "row",
105+
alignItems: "center",
106+
paddingHorizontal: 16,
107+
paddingVertical: 12,
108+
backgroundColor: "#fff",
109+
},
110+
itemText: {
111+
flex: 1,
112+
},
113+
title: {
114+
fontSize: 16,
115+
color: "#333",
116+
},
117+
time: {
118+
fontSize: 12,
119+
color: "#888",
120+
marginTop: 4,
121+
},
122+
separator: {
123+
height: 1,
124+
backgroundColor: "#eee",
125+
marginLeft: 16,
126+
width: "100%",
127+
},
61128
});

backend/app/api/routes/notifications.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from datetime import datetime
1+
from datetime import date, datetime, timedelta
2+
from typing import List
23
import uuid
34

45
from fastapi import APIRouter, Depends, HTTPException
@@ -69,3 +70,39 @@ def schedule_reminder_endpoint(
6970
return {"status": "scheduled", "reminder_id": rem_obj.id}
7071
except ValueError as e:
7172
raise HTTPException(status_code=404, detail=str(e))
73+
74+
class QuoteOut(BaseModel):
75+
date: date
76+
text: str
77+
78+
PRESET_QUOTES = [
79+
"Believe you can and you’re halfway there.",
80+
"Fall seven times, stand up eight.",
81+
"Your limitation—it’s only your imagination.",
82+
"Push yourself, because no one else is going to do it for you.",
83+
"Great things never come from comfort zones.",
84+
"Dream it. Wish it. Do it.",
85+
"Success doesn’t just find you—you have to go out and get it.",
86+
]
87+
88+
@router.get("/quotes", response_model=List[QuoteOut])
89+
def get_daily_quotes():
90+
"""
91+
Return a list of the past 7 days (including today) with
92+
one motivational quote per day, in descending date order.
93+
"""
94+
today = date.today()
95+
results: List[QuoteOut] = []
96+
97+
for i in range(7):
98+
d = today - timedelta(days=i)
99+
# determine which quote to use for date d
100+
# calculate day-of-year for d
101+
start_of_year = date(d.year, 1, 1)
102+
day_of_year = (d - start_of_year).days
103+
idx = day_of_year % len(PRESET_QUOTES)
104+
quote_text = PRESET_QUOTES[idx]
105+
106+
results.append(QuoteOut(date=d, text=quote_text))
107+
108+
return results

0 commit comments

Comments
 (0)