Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feature/mb stock details #543

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 34 additions & 12 deletions mobile/src/pages/Markets.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,23 @@ const Markets = ({ navigation }) => {

const renderStockItem = ({ item }) => (
<TouchableOpacity
style={styles.stockCard}
onPress={() => navigation.navigate('StockDetails', { id: item.id })}
>
<View>
<Text style={styles.stockCode}>{item.symbol || 'N/A'}</Text>
<Text style={styles.stockName}>{item.name || 'No Name'}</Text>
</View>
<Text style={styles.stockPrice}>
{parseFloat(item.price || 0).toFixed(2)} {item.currency?.code || ''}
</Text>
</TouchableOpacity>
style={styles.stockCard}
onPress={() => navigation.navigate('StockDetails', { id: item.id })}
>
<View style={styles.stockTextContainer}>
<Text style={styles.stockCode}>{item.symbol || 'N/A'}</Text>
<Text numberOfLines={1} ellipsizeMode="tail" style={styles.stockName}>
{item.name || 'No Name'}
</Text>
</View>
<View>
<Text style={styles.stockPrice}>
{parseFloat(item.price || 0).toFixed(2)}{' '}
{item.currency === 2 ? 'TRY' : item.currency === 3 ? 'USD' : 'N/A'}
</Text>
</View>
</TouchableOpacity>

);

if (loading) {
Expand Down Expand Up @@ -216,6 +222,22 @@ const styles = StyleSheet.create({
searchLoader: {
marginBottom: 10,
},
stockTextContainer: {
flex: 1, // Ensures the name and code take up available space
marginRight: 10, // Adds spacing between the name and the price
},
stockName: {
fontSize: 14,
color: '#333333',
marginTop: 5, // Adds spacing between the code and name
},
stockPrice: {
fontSize: 16,
fontWeight: '600',
color: '#4CAF50',
textAlign: 'right', // Aligns the price text to the right
},

loaderContainer: {
flex: 1,
justifyContent: 'center',
Expand Down Expand Up @@ -243,7 +265,7 @@ const styles = StyleSheet.create({
stockName: {
fontSize: 14,
color: '#333333',
marginTop: 4,
paddingTop: 20,
},
stockPrice: {
fontSize: 16,
Expand Down
3 changes: 2 additions & 1 deletion mobile/src/pages/PortfolioDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const PortfolioDetails = ({ route, navigation }) => {
const [selectedStock, setSelectedStock] = useState(null);
const [searchLoading, setSearchLoading] = useState(false);


const predefinedColors = ['#1E90FF', '#FFD700', '#8A2BE2', '#FF8C00', '#00CED1'];

const generateColor = () => {
Expand Down Expand Up @@ -384,7 +385,7 @@ const PortfolioDetails = ({ route, navigation }) => {

<TextInput
style={styles.input}
placeholder="Price Bought (TRY)"
placeholder={`Price Bought (${selectedStock?.currency === 2 ? 'TRY' : selectedStock?.currency === 3 ? 'USD' : ''})`}
keyboardType="numeric"
placeholderTextColor="#000"
value={priceBought}
Expand Down
105 changes: 104 additions & 1 deletion mobile/src/pages/StockDetails.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, ActivityIndicator, ScrollView, Alert } from 'react-native';
import { View, Dimensions, Text, StyleSheet, ActivityIndicator, ScrollView, Alert } from 'react-native';
import { LineChart } from 'react-native-chart-kit';

const StockDetails = ({ route }) => {
const { id } = route.params; // Get the stock ID from navigation params
const [stockDetails, setStockDetails] = useState(null);
const [loading, setLoading] = useState(true);
const [stockData, setStockData] = useState([]);
const [stockDates, setStockDates] = useState([]);
const [graphLoading, setGraphLoading] = useState(false);

const fetchStockDetails = async () => {
const url = `http://159.223.28.163:30002/stocks/${id}/`;
Expand Down Expand Up @@ -33,9 +37,47 @@ const StockDetails = ({ route }) => {
setLoading(false);
}
};
// Fetch historical stock data
const fetchStockData = async () => {
setGraphLoading(true);
try {
const response = await fetch(
`http://159.223.28.163:30002/stocks/${id}/get_historical_data/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ZnVya2Fuc2Vua2FsOkxvc29sdmlkYWRvcy41NQ==',
},
body: JSON.stringify({
period: '1mo', // Default time range
interval: '1d', // Default interval
}),
}
);

const data = await response.json();
if (data.Close && data.Date) {
setStockData(data.Close); // Set closing prices
setStockDates(
data.Date.map((date) =>
new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
)
);
} else {
console.error('Unexpected response structure:', data);
}
} catch (error) {
console.error('Error fetching stock data:', error);
Alert.alert('Error', 'Unable to fetch historical stock data.');
} finally {
setGraphLoading(false);
}
};

useEffect(() => {
fetchStockDetails();
fetchStockData();
}, [id]);

if (loading) {
Expand Down Expand Up @@ -91,6 +133,47 @@ const StockDetails = ({ route }) => {
</Text>
<Text style={styles.subDetail}>Current Price</Text>
</View>
{/* Historical Stock Data Graph */}
<View style={[styles.section, styles.graphSection]}>
<Text style={styles.sectionTitle}>Stock Price History</Text>
{graphLoading ? (
<ActivityIndicator size="large" color="#007AFF" />
) : stockData.length > 0 && stockDates.length > 0 ? (
<View style={styles.graphContainer}>
<LineChart
data={{
labels: stockDates,
datasets: [{ data: stockData }],
}}
width={Dimensions.get('window').width - 50} // Adjust width with padding
height={300}
yAxisLabel= {`${currencyCode}`}
verticalLabelRotation={60}
chartConfig={{
backgroundColor: '#fff',
backgroundGradientFrom: '#fff',
backgroundGradientTo: '#fff',
decimalPlaces: 2,
color: (opacity = 1) => `rgba(0, 123, 255, ${opacity})`,
labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
style: {
borderRadius: 16,
},
propsForDots: {
r: '4',
strokeWidth: '2',
stroke: '#007AFF',
},
}}
bezier
style={styles.chart}
/>
</View>
) : (
<Text style={styles.noDataText}>No historical stock data available.</Text>
)}
</View>


{/* Stock Highlights */}
<View style={styles.section}>
Expand Down Expand Up @@ -159,6 +242,26 @@ const styles = StyleSheet.create({
color: 'red',
textAlign: 'center',
},
chart: {
marginVertical: 8,
borderRadius: 16,
},
graphSection: {
alignItems: 'center',
justifyContent: 'center',
},
graphContainer: {
alignSelf: 'center', // Center the graph horizontally
paddingHorizontal: 8, // Add padding for the graph container
marginTop: 10,
},
noDataText: {
textAlign: 'center',
fontSize: 16,
color: '#555',
marginTop: 10,
},

container: {
padding: 16,
backgroundColor: '#f4f4f4',
Expand Down