Skip to content

Commit

Permalink
implemented viewmode picker & buttons visuals
Browse files Browse the repository at this point in the history
  • Loading branch information
ebbmango committed Dec 23, 2024
1 parent f69c160 commit 7c3d122
Show file tree
Hide file tree
Showing 11 changed files with 493 additions and 26 deletions.
2 changes: 1 addition & 1 deletion components/Screens/Create/MacrosBarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function MacrosBarChart({ fat, carbs, protein }: MacrosBarChartPr

const macros: macro[] = [
{ color: colors.get('fat'), icon: 'bacon-solid', amount: fat },
{ color: colors.get('carbohydrates'), icon: 'wheat-solid', amount: carbs },
{ color: colors.get('carbs'), icon: 'wheat-solid', amount: carbs },
{ color: colors.get('protein'), icon: 'meat-solid', amount: protein },
];

Expand Down
73 changes: 73 additions & 0 deletions components/Screens/Read/MacrosGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import IconSVG from 'components/Shared/icons/IconSVG';
import { useColors } from 'context/ColorContext';
import { Dimensions, StyleSheet } from 'react-native';
import { Colors, Text, View } from 'react-native-ui-lib';
import SegmentedMacrosBarChart from './SegmentedMacrosBarChart';

export default function MacrosGrid({ protein, carbs, fat, kcal }) {
const colors = useColors();
const screenWidth = Dimensions.get('window').width;

const macros = {
fat: {
amount: fat,
unit: 'g',
icon: 'bacon-solid',
accentColor: Colors.violet60,
},
carbs: {
amount: carbs,
unit: 'g',
icon: 'wheat-solid',
accentColor: Colors.violet50,
},
protein: {
amount: protein,
unit: 'g',
icon: 'meat-solid',
accentColor: Colors.violet40,
},
kcals: {
amount: kcal,
unit: 'kcal',
icon: 'ball-pile-solid',
accentColor: Colors.violet30,
},
};

return (
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 4 }}>
{Object.entries(macros).map(([key, macro]) => (
<View
style={[
styles.gridItem,
{ width: (screenWidth - 44) / 2, backgroundColor: colors.get(key) },
]}>
<IconSVG name={macro.icon} color={macro.accentColor} width={40} />
<Text style={styles.gridText}>
{macro.amount} {macro.unit}
</Text>
<SegmentedMacrosBarChart />
</View>
))}
</View>
);
}

const styles = StyleSheet.create({
gridItem: {
flexDirection: 'row',
height: 60,
borderRadius: 4,
alignItems: 'center',
paddingHorizontal: 20,
},
gridText: {
flex: 1,
textAlign: 'center',
fontSize: 20,
color: Colors.violet80,
fontWeight: 500,
paddingLeft: 10,
},
});
57 changes: 57 additions & 0 deletions components/Screens/Read/SegmentedMacrosBarChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import IconSVG from 'components/Shared/icons/IconSVG';
import { useColors } from 'context/ColorContext';
import React from 'react';
import { StyleSheet } from 'react-native';
import { Colors, Text, View } from 'react-native-ui-lib';

export default function SegmentedMacrosBarChart() {
const colors = useColors();

return (
<View>
<MacroMathView icon={'bacon-solid'} color={colors.get('fat')} />
<MacroMathView icon={'wheat-solid'} color={colors.get('carbs')} />
<MacroMathView icon={'meat-solid'} color={colors.get('protein')} />
<MacroMathView icon={'ball-pile-solid'} color={colors.get('kcals')} />
</View>
);
}

function MacroMathView({ color, icon }) {
return (
<View style={[styles.flex, { backgroundColor: color }]}>
{/* macro icon */}
<IconSVG name={icon} width={28} color={'white'} style={{ marginRight: 8 }} />
{/* current amount */}
<Text style={styles.text}>0g</Text>
{/* plus sign */}
<IconSVG name="plus-solid" width={20} color={'white'} style={{ marginHorizontal: 8 }} />
{/* amount to be added */}
<Text style={styles.text}>0g</Text>
{/* equals sign */}
<IconSVG name="equals-solid" width={20} color={'white'} style={{ marginHorizontal: 8 }} />
{/* resulting amount */}
<Text style={styles.text}>0g</Text>
</View>
);
}

const styles = StyleSheet.create({
text: {
flex: 1,
color: 'white',
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 18,
},
flex: {
flex: 1,
flexDirection: 'row',
height: 48,
backgroundColor: Colors.violet30,
alignItems: 'center',
paddingHorizontal: 12,

// borderRadius: 8,
},
});
121 changes: 121 additions & 0 deletions components/Screens/Read/ToggleView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { useState, useEffect } from 'react';
import { StyleSheet } from 'react-native';
import { Pressable } from 'react-native-gesture-handler';
import { Colors, Text, View } from 'react-native-ui-lib';
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
import IconSVG from 'components/Shared/icons/IconSVG';
import { ViewMode } from 'screens/Read';

// Define the structure for each mode
const MODES: { mode: ViewMode; label: string }[] = [
{ mode: ViewMode.Simple, label: 'Simple' },
{ mode: ViewMode.Meal, label: 'Meal' },
{ mode: ViewMode.Day, label: 'Day' },
];

// Define the Props Interface
interface ToggleViewProps {
viewMode: ViewMode;
setViewMode: (mode: ViewMode) => void;
}

// ToggleButton Component
interface ToggleButtonProps {
label: string;
isSelected: boolean;
onPress: () => void;
}

const ToggleButton: React.FC<ToggleButtonProps> = ({ label, isSelected, onPress }) => {
// Shared values for animation
const scale = useSharedValue(1);
const color = useSharedValue(Colors.grey40);

// Animated style
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
color: color.value,
}));

// Effect to handle animations based on selection
useEffect(() => {
if (isSelected) {
scale.value = withTiming(1.1, { duration: 200 });
color.value = Colors.violet30;
} else {
scale.value = withTiming(1, { duration: 200 });
color.value = Colors.grey40;
}
}, [isSelected, scale, color]);

return (
<Pressable style={styles.button} onPress={onPress}>
<Animated.Text style={[styles.text, animatedStyle]}>{label}</Animated.Text>
</Pressable>
);
};

// Main ToggleView Component
const ToggleView: React.FC<ToggleViewProps> = ({ viewMode, setViewMode }) => {
return (
<View style={styles.container}>
{/* Animated Background Circle */}
<View style={styles.circle}>
<IconSVG
name="table-layout-regular"
color={'white'}
width={20}
style={{ margin: 'auto' }}
/>
</View>

{/* Toggle Buttons */}
<View style={styles.buttonsContainer}>
{MODES.map(({ mode, label }) => (
<ToggleButton
key={mode}
label={label}
isSelected={viewMode === mode}
onPress={() => setViewMode(mode)}
/>
))}
</View>
</View>
);
};

export default ToggleView;

// Stylesheet
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
backgroundColor: Colors.white,
borderRadius: 100,
height: 40,
alignItems: 'center',
justifyContent: 'center',
position: 'relative', // Needed for the animated background
},
circle: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: Colors.violet30,
alignItems: 'center',
justifyContent: 'center',
},
buttonsContainer: {
flexDirection: 'row',
flex: 1,
},
button: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 16,
textAlign: 'center',
},
});
12 changes: 12 additions & 0 deletions components/Shared/icons/SVGs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,20 @@ const SVGs = {
"arrow-right-solid": {
"viewBox": "0 0 448 512",
"path": "M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z"
},
"equals-solid": {
"viewBox": "0 0 448 512",
"path": "M48 128c-17.7 0-32 14.3-32 32s14.3 32 32 32l352 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L48 128zm0 192c-17.7 0-32 14.3-32 32s14.3 32 32 32l352 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L48 320z"
},
"table-layout-regular": {
"viewBox": "0 0 512 512",
"path":
"M448 80c8.8 0 16 7.2 16 16l0 64L48 160l0-64c0-8.8 7.2-16 16-16l384 0zM48 416l0-208 96 0 0 224-80 0c-8.8 0-16-7.2-16-16zm144 16l0-224 272 0 0 208c0 8.8-7.2 16-16 16l-256 0zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32z"
// "M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zM448 96l0 64L64 160l0-64 384 0zM64 224l64 0 0 192-64 0 0-192zm384 0l0 192-256 0 0-192 256 0z"
}
} as const;




export default SVGs;
17 changes: 8 additions & 9 deletions context/ColorContext.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { createContext, useContext, useState, ReactNode } from "react";
import { Colors } from "react-native-ui-lib";
import React, { createContext, useContext, useState, ReactNode } from 'react';
import { Colors } from 'react-native-ui-lib';

export type MacroColors = {
fat: string;
protein: string;
carbohydrates: string;
calories: string;
carbs: string;
kcals: string;
};

type ColorsContextType = {
Expand All @@ -22,9 +22,9 @@ const ColorsContext = createContext<ColorsContextType | null>(null);
export function ColorsProvider({ children }: ColorsProviderProps) {
const [colors, setColors] = useState({
fat: Colors.violet50,
carbohydrates: Colors.violet40,
carbs: Colors.violet40,
protein: Colors.violet30,
calories: Colors.violet10,
kcals: Colors.violet10,
});

const updateColor = (macro: string, color: string) => {
Expand All @@ -39,8 +39,7 @@ export function ColorsProvider({ children }: ColorsProviderProps) {
value={{
get: (key) => colors[key],
set: updateColor,
}}
>
}}>
{children}
</ColorsContext.Provider>
);
Expand All @@ -50,7 +49,7 @@ export function ColorsProvider({ children }: ColorsProviderProps) {
export const useColors = () => {
const context = useContext(ColorsContext);
if (!context) {
throw new Error("useColor must be used within a ColorProvider");
throw new Error('useColor must be used within a ColorProvider');
}
return context;
};
18 changes: 9 additions & 9 deletions screens/Create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export default function Create() {
<MacroInputField
text={carbs}
onChangeText={(text) => setCarbs(text)}
color={colors.get('carbohydrates')}
color={colors.get('carbs')}
unitSymbol={'g'}
iconName={'wheat-solid'}
maxLength={7}
Expand Down Expand Up @@ -215,6 +215,14 @@ export default function Create() {
}

const styles = StyleSheet.create({
unitPickerFlex: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 160,
width: 128,
gap: 8,
},
unitIconBox: {
position: 'relative',
justifyContent: 'center',
Expand Down Expand Up @@ -246,12 +254,4 @@ const styles = StyleSheet.create({
gap: 20,
padding: 20,
},
unitPickerFlex: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 160,
width: 128,
gap: 8,
},
});
Loading

0 comments on commit 7c3d122

Please sign in to comment.