From 2505fc1bf7598cbce9c4d0a2d9635595397f4efd Mon Sep 17 00:00:00 2001 From: Loewy Date: Tue, 20 Feb 2024 18:49:08 -0800 Subject: [PATCH] make some components, almost done, need to do ui for notes/free play --- src/component/image/image-with-fallback.tsx | 26 ++++ src/component/modals/session-details.tsx | 114 ------------------ .../stat-details/session-details.tsx | 93 ++++++++++++++ src/component/stat-details/stat-item.tsx | 50 ++++++++ src/styles.ts | 16 +-- test/mock/charts/mock-data.ts | 11 ++ 6 files changed, 189 insertions(+), 121 deletions(-) create mode 100644 src/component/image/image-with-fallback.tsx delete mode 100644 src/component/modals/session-details.tsx create mode 100644 src/component/stat-details/session-details.tsx create mode 100644 src/component/stat-details/stat-item.tsx diff --git a/src/component/image/image-with-fallback.tsx b/src/component/image/image-with-fallback.tsx new file mode 100644 index 0000000..b2a914c --- /dev/null +++ b/src/component/image/image-with-fallback.tsx @@ -0,0 +1,26 @@ +import React, { useState } from "react"; +import { Image } from "react-native"; + +type ImageWithFallbackProps = { + source: { uri: string }; + fallbackSource?: { uri: string }; + style?: object; +}; + +const ImageWithFallback: React.FC = ({ + source, + fallbackSource, + style, +}) => { + const [imageSource, setImageSource] = useState(source); + + const handleError = () => { + if (fallbackSource) { + setImageSource(fallbackSource); + } + }; + + return ; +}; + +export default ImageWithFallback; diff --git a/src/component/modals/session-details.tsx b/src/component/modals/session-details.tsx deleted file mode 100644 index 8cb9308..0000000 --- a/src/component/modals/session-details.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React, { useState } from "react"; -import { Image, StyleSheet, Text, View } from "react-native"; - -export default function SessionDetails() { - // Modal State - const [visible, setVisible] = useState(false); - - // Stats State - // TODO: needs to come from session context - const [sessionTitle, setSessionTitle] = useState("Afternoon Session"); - const [date, setDate] = useState("Today at 2:37pm"); - const [timePlayed, setTimePlayed] = useState("5:03:10"); - const [medianRun, setMedianRun] = useState("7.3"); - const [makeRate, setMakeRate] = useState("34%"); - const [shotPacing, setShotPacing] = useState("0:00:26"); - const [gameType, setGameType] = useState("Free Play"); - const [notes, setNotes] = useState( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit...", - ); - - return ( - - - {sessionTitle} - {date} - - - - - - TIME PLAYED - {timePlayed} - - - MEDIAN RUN - {medianRun} - - - - - MAKE RATE - {makeRate} - - - SHOT PACING - {shotPacing} - - - - {/* USE A BETTER SYSTEM FOR THE DIVIDER, COULD ATTACH TO OTHER COMPONENT */} - - {gameType} - {notes} - - ); -} - -const styles = StyleSheet.create({ - headerSection: { - paddingHorizontal: 20, - paddingVertical: 15, - }, - header: { - fontSize: 24, - fontWeight: "bold", - }, - image: { - width: "100%", - height: 248, - }, - statsContainer: { - flexDirection: "row", - justifyContent: "space-between", - padding: 20, - }, - statColumn: { - flex: 1, - padding: 5, - }, - statItem: { - borderLeftWidth: 0.5, - borderRightColor: "lightgrey", - marginBottom: 10, - }, - statLabel: { - fontSize: 16, - color: "grey", - textAlign: "center", - }, - statValue: { - fontSize: 28, - fontWeight: "bold", - textAlign: "center", - }, - horizontalDivider: { - borderBottomWidth: 0.5, - color: "lightgrey", - width: "90%", - alignSelf: "center", - }, - gameType: { - fontSize: 18, - textAlign: "center", - marginTop: 10, - }, - notes: { - fontSize: 16, - color: "grey", - padding: 20, - }, -}); diff --git a/src/component/stat-details/session-details.tsx b/src/component/stat-details/session-details.tsx new file mode 100644 index 0000000..f68c36e --- /dev/null +++ b/src/component/stat-details/session-details.tsx @@ -0,0 +1,93 @@ +import React from "react"; +import { StyleSheet, Text, View } from "react-native"; +import { mock_session_details } from "../../../test/mock/charts/mock-data"; +import ImageWithFallback from "../image/image-with-fallback"; +import StatList from "./stat-item"; + +import Splash from "../../assets/splash.png"; + +export default function SessionDetails() { + // Remove mock destructure when data is piped through from BE + const { + sessionTitle, + date, + timePlayed, + medianRun, + makeRate, + shotPacing, + gameType, + notes, + } = mock_session_details; + + const leftColumnStats = [ + { title: "TIME PLAYED", value: timePlayed }, + { title: "MEDIAN RUN", value: medianRun }, + ]; + + const rightColumnStats = [ + { title: "MAKE RATE", value: makeRate }, + { title: "SHOT PACING", value: shotPacing }, + ]; + + return ( + + + {sessionTitle} + {date} + + + + + + + {/* USE A BETTER SYSTEM FOR THE DIVIDER, COULD ATTACH TO OTHER COMPONENT */} + + {gameType} + {notes} + + ); +} + +const styles = StyleSheet.create({ + headerSection: { + paddingHorizontal: 20, + paddingVertical: 15, + }, + header: { + fontSize: 24, + fontWeight: "bold", + }, + image: { + width: "100%", + height: 248, + }, + statsContainer: { + flexDirection: "row", + justifyContent: "space-between", + padding: 20, + }, + statColumn: { + flex: 1, + padding: 5, + }, + horizontalDivider: { + borderBottomWidth: 0.5, + color: "lightgrey", + width: "90%", + alignSelf: "center", + }, + gameType: { + fontSize: 18, + textAlign: "center", + marginTop: 10, + }, + notes: { + fontSize: 16, + color: "grey", + padding: 20, + }, +}); diff --git a/src/component/stat-details/stat-item.tsx b/src/component/stat-details/stat-item.tsx new file mode 100644 index 0000000..b76e40b --- /dev/null +++ b/src/component/stat-details/stat-item.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { StyleSheet, Text, View } from "react-native"; + +type StatItem = { + title: string; + value: string; +}; + +type StatListProps = { + items: StatItem[]; + style?: object; +}; + +const StatList: React.FC = ({ items, style }) => { + return ( + + {items.map((item, index) => ( + + {item.title} + {item.value} + + ))} + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: "column", + flex: 1, + padding: 5, + }, + item: { + borderLeftWidth: 0.5, + borderRightColor: "lightgrey", + marginBottom: 10, + }, + title: { + fontSize: 16, + color: "grey", + textAlign: "center", + }, + value: { + fontSize: 28, + fontWeight: "bold", + textAlign: "center", + }, +}); + +export default StatList; diff --git a/src/styles.ts b/src/styles.ts index bed1654..e37ec7d 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -1,7 +1,14 @@ import Constants from "expo-constants"; import { Platform, StyleSheet } from "react-native"; -// GLOBAL STYLES +// STYLE CONSTS +let STATUS_BAR_HEIGHT: number; + +Platform.OS === "android" + ? (STATUS_BAR_HEIGHT = 24) + : (STATUS_BAR_HEIGHT = Constants.statusBarHeight | 24); + +// GLOBALLY STYLED export const globalInputStyles = StyleSheet.create({ input: { width: "100%", @@ -30,12 +37,6 @@ export const globalInputStyles = StyleSheet.create({ }, }); -let STATUS_BAR_HEIGHT: number; - -Platform.OS === "android" - ? (STATUS_BAR_HEIGHT = 24) - : (STATUS_BAR_HEIGHT = Constants.statusBarHeight | 24); - // COLORS: // can be made more granular to specify utility (ex: fontColors vs backgroundColors) export const colors = { @@ -55,6 +56,7 @@ export const tabIconColors = { selected: "#598EBB", }; +// SHADOWS export const shadows = { standard: { shadowColor: "#000000", diff --git a/test/mock/charts/mock-data.ts b/test/mock/charts/mock-data.ts index 3a7e472..f764a06 100644 --- a/test/mock/charts/mock-data.ts +++ b/test/mock/charts/mock-data.ts @@ -97,3 +97,14 @@ export const mockYData = [ ]; export const mockXValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +export const mock_session_details = { + sessionTitle: "Afternoon Session", + date: "Today at 2:37pm", + timePlayed: "5:03:10", + medianRun: "7.3", + makeRate: "34%", + shotPacing: "0:00:26", + gameType: "Free Play", + notes: "Lorem ipsum dolor sit amet, consectetur adipiscing elit...", +};