diff --git a/__fixtures__/initialProducts.ts b/__fixtures__/initialProducts.ts index 82023d1..058209b 100644 --- a/__fixtures__/initialProducts.ts +++ b/__fixtures__/initialProducts.ts @@ -2,7 +2,7 @@ import { Product } from "@/lib/product"; export const products = [ // Sheet goods - new Product(25, {l: 4, w : 8, u: "ft"}, { name: "Plywood 1/4\"" }), + new Product(15, {l: 4, w : 8, u: "ft"}, { name: "Plywood 1/4\"" }), new Product(20, {l: 4, w : 8, u: "ft"}, { name: "Plywood 1/2\"" }), new Product(25, {l: 4, w : 8, u: "ft"}, { name: "Plywood 3/4\"" }), new Product(5, {l: 4, w : 8, u: "ft"}, { name: "Thin Panel Board" }), diff --git a/app.json b/app.json index 9b5f43f..2c03411 100644 --- a/app.json +++ b/app.json @@ -2,10 +2,11 @@ "expo": { "name": "PliWould", "slug": "PliWould", + "scheme": "tech.damngood.PliWould", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/images/icon.png", - "scheme": "myapp", + "entrypoint": "./app/app.tsx", "userInterfaceStyle": "automatic", "splash": { "image": "./assets/images/splash.png", diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index f384b5a..8db0aa3 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -10,7 +10,8 @@ import { setupStore } from '../store'; export default function TabLayout() { const colorScheme = useColorScheme(); const store = setupStore({ - products: fixtures.map(p => p.asObject) + products: fixtures.map(p => p.asObject), + units: "ft", }); return ( @@ -22,7 +23,7 @@ export default function TabLayout() { ( ), @@ -31,7 +32,7 @@ export default function TabLayout() { ( ), diff --git a/app/store.ts b/app/store.ts index 939e7c7..9756927 100644 --- a/app/store.ts +++ b/app/store.ts @@ -3,25 +3,29 @@ import { configureStore } from '@reduxjs/toolkit'; import { rememberReducer, rememberEnhancer } from 'redux-remember'; import reducers from "@/features/product/productSlice" import AsyncStorage from '@react-native-async-storage/async-storage'; -import { Product, ProductData, } from "@/lib/product"; +import { ProductData, } from "@/lib/product"; +import {Length} from "convert" const rememberedKeys = ['products']; const rootReducer = reducers; +const isBrowser = (typeof window !== "undefined"); + export function setupStore(preloadedState = { products: [] as ProductData[], + units: "ft" as Length, }) { return configureStore({ reducer: rememberReducer(reducers), preloadedState, enhancers: (getDefaultEnhancers) => getDefaultEnhancers().concat( rememberEnhancer( - AsyncStorage, + isBrowser ? window.localStorage : AsyncStorage, rememberedKeys, { - persistWholeStore: true, - } + persistWholeStore: false, + }, ) ), }); diff --git a/components/AreaInput.tsx b/components/AreaInput.tsx index 9979375..929f0e0 100644 --- a/components/AreaInput.tsx +++ b/components/AreaInput.tsx @@ -1,18 +1,21 @@ import { MeasurementInput } from "./MeasurementInput"; import { area_t, dimensions_t } from "@/lib/product"; +import { Length } from "convert"; import { useState } from "react"; -import { StyleSheet, View } from "react-native"; +import { StyleSheet, Text, View } from "react-native"; export type AreaInputProps = { onMeasurementSet?: (area : dimensions_t) => any, defaultValue?: area_t, lengthLabel?: string, widthLabel?: string, + units?: Length, } -export function AreaInput({onMeasurementSet, lengthLabel, widthLabel, defaultValue} : AreaInputProps) { +export function AreaInput({onMeasurementSet, lengthLabel, widthLabel, defaultValue, units} : AreaInputProps) { defaultValue = defaultValue || {l: 0, w: 0, u: "ft"} + units = units || "ft" const [area, setArea] = useState(defaultValue) @@ -44,11 +47,14 @@ export function AreaInput({onMeasurementSet, lengthLabel, widthLabel, defaultVal defaultValue={{l: area.l, u: area.u}} onValueSet={doOnLengthSet} label={lengthLabel} + units={units} /> + x ) @@ -56,6 +62,7 @@ export function AreaInput({onMeasurementSet, lengthLabel, widthLabel, defaultVal const styles = StyleSheet.create({ areaInputWrapper: { - flexDirection: "row" + flexDirection: "row", + verticalAlign: "middle", } }) \ No newline at end of file diff --git a/components/MeasurementInput.tsx b/components/MeasurementInput.tsx index 326c97f..193ca8f 100644 --- a/components/MeasurementInput.tsx +++ b/components/MeasurementInput.tsx @@ -9,13 +9,16 @@ export type MeasurementInputProps = { onValueSet?: (d: dimensions_t) => any, defaultValue: length_t; label?: string, + units?: Length, } -export function MeasurementInput({onValueSet, defaultValue, label}: MeasurementInputProps) { +export function MeasurementInput({onValueSet, defaultValue, label, units}: MeasurementInputProps) { const [mValue, setMValue] = useState(defaultValue) const defValue = Number.isNaN(defaultValue.l) ? 0 : defaultValue.l + units = units || "ft"; + function doOnValueSet(value : string) { setMValue(mValue); const iVal = parseFloat(value) || parseInt(value); @@ -37,7 +40,7 @@ export function MeasurementInput({onValueSet, defaultValue, label}: MeasurementI style={styles.lengthInput} aria-label={label || "Enter measurement"} /> - {mValue.u} + {units} ) } @@ -45,10 +48,13 @@ export function MeasurementInput({onValueSet, defaultValue, label}: MeasurementI const styles = StyleSheet.create({ inputWrapper: { alignItems: "flex-start", - flexDirection: "row" + flexDirection: "row", + verticalAlign: "middle" }, unitHints: { padding: 10, + fontSize: 20, + verticalAlign: "middle", }, lengthInput: { borderWidth: 1, diff --git a/components/PercentDamange.tsx b/components/PercentDamange.tsx index 635b779..16df4ec 100644 --- a/components/PercentDamange.tsx +++ b/components/PercentDamange.tsx @@ -1,27 +1,36 @@ import { StyleSheet, Text, TextInput, View } from "react-native"; import Slider from '@react-native-community/slider'; -import { useState } from "react"; +import { useEffect, useState } from "react"; type PercentDamageProps = { onSetPercentage: (percent: number) => any; } -export default function PercentDamage ({onSetPercentage} : PercentDamageProps) { +function getDamangeColor(damage : number) { + if (damage === 0) return "black"; + if (damage <= 20) return "blue"; + if (damage <= 50) return "orange"; + return "red"; +} + +export default function PercentDamage({ onSetPercentage }: PercentDamageProps) { const [damage, setDamage] = useState(0); - function doOnChangeText (val : number) { - setDamage(val); - onSetPercentage(val / 100); + const [damageColor, setDamageColor] = useState("black"); + function doOnChangeText(val: number) { + setDamage(val || 0); + onSetPercentage((val / 100) || 0); + setDamageColor(getDamangeColor(val || 0)); } + return ( - {damage}% Damage + /> + {damage}% Damage ) } @@ -40,5 +49,9 @@ const styles = StyleSheet.create({ }, label: { margin: 5, + alignSelf: "center", + fontSize: 20, + fontWeight: "bold", + fontStyle: "italic", } }) \ No newline at end of file diff --git a/components/ProductCalculatorSelector.tsx b/components/ProductCalculatorSelector.tsx index e1948b3..68d997e 100644 --- a/components/ProductCalculatorSelector.tsx +++ b/components/ProductCalculatorSelector.tsx @@ -83,12 +83,14 @@ export default function ProductCalculatorSelector() { onMeasurementSet={onMeasurementSet} widthLabel='enter width' lengthLabel='enter length' + units={measurement.u} /> : ) : ( @@ -101,7 +103,7 @@ export default function ProductCalculatorSelector() { {activeProduct && - ( + ( @@ -129,6 +131,7 @@ export const styles = StyleSheet.create({ inputWrapper: { flexDirection: "row", alignItems: "flex-start", + verticalAlign: "middle", }, unitSelector: { }, @@ -195,4 +198,9 @@ export const styles = StyleSheet.create({ padding: 4, }, + damageWrapper: { + paddingVertical: 10, + paddingHorizontal: 10, + }, + }); diff --git a/components/UnitChooser.tsx b/components/UnitChooser.tsx index 3a75891..c1f4a6e 100644 --- a/components/UnitChooser.tsx +++ b/components/UnitChooser.tsx @@ -1,16 +1,17 @@ import { Length } from "convert"; import { useState } from "react"; -import { Button, StyleSheet, View } from "react-native"; +import { Button, StyleSheet, Text, TouchableHighlight, View } from "react-native"; export type UnitChooserProps = { choices: Length[], onChoicePressed: (l: Length) => any, activeColor?: string, defaultColor?: string, + defaultValue? : Length, } -export default function UnitChooser({ choices, onChoicePressed, activeColor, defaultColor }: UnitChooserProps) { - const [value, setValue] = useState(choices[0] as Length); +export default function UnitChooser({ choices, onChoicePressed, activeColor, defaultColor, defaultValue }: UnitChooserProps) { + const [value, setValue] = useState(defaultValue || choices[0] as Length); activeColor = activeColor || "lightblue"; defaultColor = defaultColor || "lightgrey"; @@ -24,11 +25,13 @@ export default function UnitChooser({ choices, onChoicePressed, activeColor, def {choices.map((ci) => { return ( -