global darkmode hook usage; use style abstractions; remove ui wrapper causing issues

This commit is contained in:
David Westgate 2025-03-17 23:10:31 -07:00
parent 68a91a32ad
commit e720e2e010
17 changed files with 268 additions and 279 deletions

View File

@ -1,9 +1,11 @@
import i18n from "@/i18n/i18n";
import { COLORS } from "@/styles/styles";
import AppContext, { IAppContext } from "@/util/context";
import { MaterialIcons } from "@expo/vector-icons";
import { Stack } from "expo-router";
import React, { useMemo, useState } from "react";
import { I18nextProvider, useTranslation } from "react-i18next";
import { useColorScheme } from "react-native";
const RootLayout: React.FC = () => {
const [showSettings, setShowSettings] = useState<boolean>(false);
@ -17,20 +19,36 @@ const RootLayout: React.FC = () => {
[showSettings]
);
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
return (
<AppContext.Provider value={ctx}>
<I18nextProvider i18n={i18n}>
<Stack
screenOptions={{
contentStyle: {
backgroundColor: colors.BACKGROUND,
},
headerShown: true,
title: t("poker_chips_helper"),
navigationBarColor: colors.PRIMARY,
headerRight: () => (
<MaterialIcons
name="settings"
onPress={() => setShowSettings(!showSettings)}
size={30}
color={colors.TEXT}
/>
),
headerStyle: {
backgroundColor: colors.PRIMARY,
},
headerTintColor: colors.TEXT,
statusBarBackgroundColor: "grey",
}}
/>
</I18nextProvider>

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect, useContext, useMemo } from "react";
import { ScrollView, Alert } from "react-native";
import { ScrollView, Alert, useColorScheme, Appearance } from "react-native";
import Button from "@/containers/Button";
import PlayerSelector from "@/components/PlayerSelector";
import BuyInSelector from "@/components/BuyInSelector";
@ -12,12 +12,11 @@ import {
savePersistentState,
loadPersistentState,
} from "@/util/PersistentState";
import styles from "@/styles/styles";
import styles, { COLORS } from "@/styles/styles";
import Section from "@/containers/Section";
import AppContext from "@/util/context";
import { Picker } from "@react-native-picker/picker";
import i18n from "@/i18n/i18n";
import PokerAppUi from "@/containers/PokerAppUi";
const IndexScreen: React.FC = () => {
const [playerCount, setPlayerCount] = useState(2);
@ -26,8 +25,12 @@ const IndexScreen: React.FC = () => {
const [totalChipsCount, setTotalChipsCount] = useState<number[]>([]);
const [selectedCurrency, setSelectedCurrency] = useState<string>("$");
const [selectedLanguage, setSelectedLanguage] = useState<string>("en");
const [lightGrayMode, setLightGrayMode] = useState<boolean>(false);
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
const context = useContext(AppContext);
const isSettingsVisible = useMemo(() => context.showSettings, [context]);
@ -87,14 +90,12 @@ const IndexScreen: React.FC = () => {
};
return (
<PokerAppUi darkMode={lightGrayMode}>
<ScrollView
/*style={styles.scrollView}
contentContainerStyle={styles.scrollViewContent}*/
style={{ flex: 1 }}
contentContainerStyle={{ paddingHorizontal: 15, paddingBottom: 30 }}
>
{isSettingsVisible && (
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollViewContent}
>
{isSettingsVisible && (
<>
<Section
title={i18n.t("appearance")}
iconName={"brightness-4"}
@ -102,17 +103,16 @@ const IndexScreen: React.FC = () => {
>
<Button
title={
lightGrayMode
darkMode
? i18n.t("switch_to_light_mode")
: i18n.t("switch_to_gray_mode")
: i18n.t("switch_to_dark_mode")
}
onPress={() =>
Appearance.setColorScheme(darkMode ? "light" : "dark")
}
onPress={() => setLightGrayMode(!lightGrayMode)}
darkMode={lightGrayMode}
/>
</Section>
)}
{isSettingsVisible && (
<Section
title={i18n.t("select_language")}
iconName={"language"}
@ -121,15 +121,28 @@ const IndexScreen: React.FC = () => {
<Picker
selectedValue={selectedLanguage}
onValueChange={handleLanguageChange}
style={styles.picker}
style={[styles.picker, { color: colors.TEXT }]}
dropdownIconColor={colors.TEXT}
>
<Picker.Item label={i18n.t("english")} value="en" />
<Picker.Item label={i18n.t("spanish")} value="es" />
<Picker.Item
label={i18n.t("english")}
value="en"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
<Picker.Item
label={i18n.t("spanish")}
value="es"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
</Picker>
</Section>
)}
{isSettingsVisible && (
<Section
title={i18n.t("select_currency")}
iconName={"attach-money"}
@ -140,105 +153,97 @@ const IndexScreen: React.FC = () => {
setSelectedCurrency={setSelectedCurrency}
/>
</Section>
)}
</>
)}
<Section
title={i18n.t("select_number_of_players")}
iconName={"people"}
orientation="row"
contentStyle={{ justifyContent: "center", gap: 30 }}
>
<PlayerSelector
playerCount={playerCount}
setPlayerCount={setPlayerCount}
darkMode={lightGrayMode}
<Section
title={i18n.t("select_number_of_players")}
iconName={"people"}
orientation="row"
contentStyle={{ justifyContent: "center", gap: 30 }}
>
<PlayerSelector
playerCount={playerCount}
setPlayerCount={setPlayerCount}
/>
</Section>
<Section
title={i18n.t("select_buyin_amount")}
iconName={"monetization-on"}
>
<BuyInSelector
selectedCurrency={selectedCurrency}
setBuyInAmount={setBuyInAmount}
/>
</Section>
<Section
title={i18n.t("automatic_chip_detection")}
iconName={"camera-alt"}
>
<ChipDetection
updateChipCount={(chipData) => {
const chipCountArray = Object.values(chipData);
setTotalChipsCount(chipCountArray);
setNumberOfChips(chipCountArray.length);
}}
/>
</Section>
<Section
title={i18n.t("manual_chip_adjustment")}
iconName={"account-balance"}
orientation="row"
contentStyle={{ alignItems: "center" }}
>
<ChipsSelector
totalChipsCount={totalChipsCount}
setTotalChipsCount={setTotalChipsCount}
numberOfChips={numberOfChips}
setNumberOfChips={setNumberOfChips}
/>
</Section>
<Section
title={i18n.t("distribution_and_denomination")}
iconName={"currency-exchange"}
>
<ChipDistributionSummary
playerCount={playerCount}
buyInAmount={buyInAmount}
totalChipsCount={totalChipsCount}
selectedCurrency={selectedCurrency}
/>
</Section>
<Section
title={i18n.t("save_and_load")}
iconName={"save"}
orientation="row"
>
<>
<Button
title={i18n.t("save_slot_1")}
onPress={() => handleSave("SLOT1")}
disabled={buyInAmount === null}
/>
</Section>
<Section
title={i18n.t("select_buyin_amount")}
iconName={"monetization-on"}
>
<BuyInSelector
selectedCurrency={selectedCurrency}
setBuyInAmount={setBuyInAmount}
darkMode={lightGrayMode}
<Button
title={i18n.t("save_slot_2")}
onPress={() => handleSave("SLOT2")}
disabled={buyInAmount === null}
/>
</Section>
<Section
title={i18n.t("automatic_chip_detection")}
iconName={"camera-alt"}
>
<ChipDetection
updateChipCount={(chipData) => {
const chipCountArray = Object.values(chipData);
setTotalChipsCount(chipCountArray);
setNumberOfChips(chipCountArray.length);
}}
darkMode={lightGrayMode}
<Button
title={i18n.t("load_slot_1")}
onPress={() => handleLoad("SLOT1")}
/>
</Section>
<Section
title={i18n.t("manual_chip_adjustment")}
iconName={"account-balance"}
orientation="row"
contentStyle={{ alignItems: "center" }}
>
<ChipsSelector
totalChipsCount={totalChipsCount}
setTotalChipsCount={setTotalChipsCount}
numberOfChips={numberOfChips}
setNumberOfChips={setNumberOfChips}
darkMode={lightGrayMode}
<Button
title={i18n.t("load_slot_2")}
onPress={() => handleLoad("SLOT2")}
/>
</Section>
<Section
title={i18n.t("distribution_and_denomination")}
iconName={"currency-exchange"}
>
<ChipDistributionSummary
playerCount={playerCount}
buyInAmount={buyInAmount}
totalChipsCount={totalChipsCount}
selectedCurrency={selectedCurrency}
/>
</Section>
<Section
title={i18n.t("save_and_load")}
iconName={"save"}
orientation="row"
>
<>
<Button
title={i18n.t("save_slot_1")}
onPress={() => handleSave("SLOT1")}
disabled={buyInAmount === null}
darkMode={lightGrayMode}
/>
<Button
title={i18n.t("save_slot_2")}
onPress={() => handleSave("SLOT2")}
disabled={buyInAmount === null}
darkMode={lightGrayMode}
/>
<Button
title={i18n.t("load_slot_1")}
onPress={() => handleLoad("SLOT1")}
darkMode={lightGrayMode}
/>
<Button
title={i18n.t("load_slot_2")}
onPress={() => handleLoad("SLOT2")}
darkMode={lightGrayMode}
/>
</>
</Section>
</ScrollView>
</PokerAppUi>
</>
</Section>
</ScrollView>
);
};

View File

@ -1,5 +1,5 @@
import React, { useState } from "react";
import { View, Text, TextInput } from "react-native";
import React, { useMemo, useState } from "react";
import { View, Text, TextInput, useColorScheme } from "react-native";
import styles, { COLORS } from "@/styles/styles";
import Button from "@/containers/Button";
import i18n from "@/i18n/i18n";
@ -7,7 +7,6 @@ import i18n from "@/i18n/i18n";
interface BuyInSelectorProps {
setBuyInAmount: React.Dispatch<React.SetStateAction<number>>;
selectedCurrency: string;
darkMode: boolean;
}
const defaultBuyInOptions = [10, 25, 50];
@ -23,10 +22,15 @@ const parseRoundClamp = (num: string): number => {
const BuyInSelector: React.FC<BuyInSelectorProps> = ({
setBuyInAmount,
selectedCurrency,
darkMode,
}) => {
const [customAmount, setCustomAmount] = useState("");
const [buyInAmount, setBuyInAmountState] = useState<number | null>(null);
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
const handleCustomAmountChange = (value: string) => {
const numericValue = parseRoundClamp(value);
@ -55,13 +59,13 @@ const BuyInSelector: React.FC<BuyInSelectorProps> = ({
key={amount}
onPress={() => handleBuyInSelection(amount)}
title={`${selectedCurrency} ${amount}`}
darkMode={darkMode}
/>
))}
</View>
<TextInput
style={styles.input}
style={[styles.input, { color: colors.TEXT }]}
placeholderTextColor={colors.TEXT}
value={customAmount}
maxLength={3}
onChangeText={handleCustomAmountChange}
@ -69,7 +73,7 @@ const BuyInSelector: React.FC<BuyInSelectorProps> = ({
keyboardType="numeric"
/>
<Text style={styles.h2}>
<Text style={[styles.h2, { color: colors.TEXT }]}>
{`${i18n.t("selected_buy_in")} `}
{buyInAmount !== null
? `${selectedCurrency} ${buyInAmount}`

View File

@ -6,10 +6,8 @@ import i18n from "@/i18n/i18n";
const ChipDetection = ({
updateChipCount,
darkMode,
}: {
updateChipCount: (chipData: Record<string, number>) => void;
darkMode: boolean;
}) => {
const [imageUri, setImageUri] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
@ -135,16 +133,8 @@ const ChipDetection = ({
marginBottom: 10,
}}
>
<Button
title={i18n.t("pick_an_image")}
onPress={pickImage}
darkMode={darkMode}
/>
<Button
title={i18n.t("take_a_photo")}
onPress={takePhoto}
darkMode={darkMode}
/>
<Button title={i18n.t("pick_an_image")} onPress={pickImage} />
<Button title={i18n.t("take_a_photo")} onPress={takePhoto} />
</View>
{imageUri && (

View File

@ -21,13 +21,11 @@ const ChipInputModal = ({
setShowModal,
totalChipsCount,
update,
darkMode,
}: {
showModal: [boolean, ColorValue];
setShowModal: React.Dispatch<React.SetStateAction<[boolean, ColorValue]>>;
totalChipsCount: number[];
update: Function;
darkMode: boolean;
}) => {
const color: ColorValue = useMemo(() => showModal[1], [showModal]);
const colorIdx = useMemo(() => colors.indexOf(color), [color]);
@ -77,7 +75,6 @@ const ChipInputModal = ({
update(showModal[1], Number.isNaN(value) ? 0 : value);
setShowModal([false, color]);
}}
darkMode={darkMode}
/>
</Modal>
);
@ -119,13 +116,11 @@ const ChipsSelector = ({
totalChipsCount,
setTotalChipsCount,
setNumberOfChips,
darkMode,
}: {
numberOfChips: number;
totalChipsCount: number[];
setTotalChipsCount: React.Dispatch<React.SetStateAction<number[]>>;
setNumberOfChips: React.Dispatch<React.SetStateAction<number>>;
darkMode: boolean;
}) => {
const [showModal, setShowModal] = useState<[boolean, ColorValue]>([
false,
@ -172,7 +167,6 @@ const ChipsSelector = ({
setNumberOfChips(Math.max(1, numberOfChips - 1));
}}
disabled={numberOfChips === 1}
darkMode={darkMode}
/>
<View style={[styles.container, { flexDirection: "row" }]}>
{colorsUsed.map((color) => {
@ -193,7 +187,6 @@ const ChipsSelector = ({
setNumberOfChips(Math.min(5, numberOfChips + 1));
}}
disabled={numberOfChips === 5}
darkMode={darkMode}
/>
<ChipInputModal
@ -201,7 +194,6 @@ const ChipsSelector = ({
setShowModal={setShowModal}
totalChipsCount={totalChipsCount}
update={update}
darkMode={darkMode}
/>
</>
);

View File

@ -1,7 +1,8 @@
import React from "react";
import React, { useMemo } from "react";
import { Picker } from "@react-native-picker/picker";
import styles from "@/styles/styles";
import styles, { COLORS } from "@/styles/styles";
import i18n from "@/i18n/i18n";
import { useColorScheme } from "react-native";
interface CurrencySelectorProps {
selectedCurrency: string;
@ -12,18 +13,53 @@ const CurrencySelector: React.FC<CurrencySelectorProps> = ({
selectedCurrency,
setSelectedCurrency,
}) => {
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
return (
<>
<Picker
selectedValue={selectedCurrency}
onValueChange={(itemValue) => setSelectedCurrency(itemValue)}
style={styles.picker}
style={[styles.picker, { color: colors.TEXT }]}
dropdownIconColor={colors.TEXT}
testID="currency-picker" // ✅ Add testID here
>
<Picker.Item label={i18n.t("usd")} value="$" />
<Picker.Item label={i18n.t("euro")} value="€" />
<Picker.Item label={i18n.t("pound")} value="£" />
<Picker.Item label={i18n.t("inr")} value="₹" />
<Picker.Item
label={i18n.t("usd")}
value="$"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
<Picker.Item
label={i18n.t("euro")}
value="€"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
<Picker.Item
label={i18n.t("pound")}
value="£"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
<Picker.Item
label={i18n.t("inr")}
value="₹"
style={{
color: colors.TEXT,
backgroundColor: colors.PRIMARY,
}}
/>
</Picker>
</>
);

View File

@ -1,12 +1,11 @@
import React from "react";
import { View, Text } from "react-native";
import React, { useMemo } from "react";
import { View, Text, useColorScheme } from "react-native";
import Button from "@/containers/Button";
import styles from "@/styles/styles";
import styles, { COLORS } from "@/styles/styles";
interface PlayerSelectorProps {
playerCount: number;
setPlayerCount: React.Dispatch<React.SetStateAction<number>>;
darkMode: boolean;
}
const MIN = 2;
@ -15,7 +14,6 @@ const MAX = 8;
const PlayerSelector: React.FC<PlayerSelectorProps> = ({
playerCount,
setPlayerCount,
darkMode,
}) => {
const increasePlayers = () => {
if (playerCount < MAX) setPlayerCount(playerCount + 1);
@ -24,21 +22,25 @@ const PlayerSelector: React.FC<PlayerSelectorProps> = ({
const decreasePlayers = () => {
if (playerCount > MIN) setPlayerCount(playerCount - 1);
};
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
return (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<View style={{ flexDirection: "row", alignItems: "center", gap: 10 }}>
<Button
title="-"
onPress={decreasePlayers}
disabled={playerCount <= MIN}
darkMode={darkMode}
/>
<Text style={styles.h1}>{playerCount}</Text>
<Text style={[styles.h1, { color: colors.TEXT }]}>{playerCount}</Text>
<Button
title="+"
onPress={increasePlayers}
disabled={playerCount >= MAX}
darkMode={darkMode}
/>
</View>
);

View File

@ -19,7 +19,6 @@ describe("BuyInSelector Component", () => {
<BuyInSelector
setBuyInAmount={setBuyInAmount}
selectedCurrency={selectedCurrency}
darkMode={false}
/>
);
return {

View File

@ -45,7 +45,7 @@ describe("ChipDetection", () => {
it("renders correctly", () => {
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
expect(getByText(/pick an image/i)).toBeTruthy();
@ -59,7 +59,7 @@ describe("ChipDetection", () => {
});
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
fireEvent.press(getByText(/pick an image/i));
@ -78,7 +78,7 @@ describe("ChipDetection", () => {
});
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
fireEvent.press(getByText(/take a photo/i));
@ -99,7 +99,7 @@ describe("ChipDetection", () => {
});
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
fireEvent.press(getByText(/take a photo/i));
@ -126,7 +126,7 @@ describe("ChipDetection", () => {
);
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
fireEvent.press(getByText(/pick an image/i));
@ -159,7 +159,7 @@ describe("ChipDetection", () => {
);
const { getByText } = render(
<ChipDetection updateChipCount={mockUpdateChipCount} darkMode={false} />
<ChipDetection updateChipCount={mockUpdateChipCount} />
);
fireEvent.press(getByText(/pick an image/i));

View File

@ -28,7 +28,6 @@ const rend = () =>
totalChipsCount={TOTAL_CHIPS_COUNT}
setTotalChipsCount={mocktTotalChipsCount}
setNumberOfChips={mockSetNumberOfChips}
darkMode={false}
/>
);

View File

@ -6,11 +6,7 @@ describe("PlayerSelector Component", () => {
it("renders the initial player count and buttons correctly", () => {
const setPlayerCount = jest.fn();
const { getByText, getByRole } = render(
<PlayerSelector
playerCount={4}
setPlayerCount={setPlayerCount}
darkMode={false}
/>
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
);
expect(getByText("4")).toBeTruthy();
@ -21,11 +17,7 @@ describe("PlayerSelector Component", () => {
it('increases player count when "+" button is pressed', () => {
const setPlayerCount = jest.fn();
const { getByRole } = render(
<PlayerSelector
playerCount={4}
setPlayerCount={setPlayerCount}
darkMode={false}
/>
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
);
fireEvent.press(getByRole("button", { name: "+" }));
@ -35,11 +27,7 @@ describe("PlayerSelector Component", () => {
it('decreases player count when "-" button is pressed', () => {
const setPlayerCount = jest.fn();
const { getByRole } = render(
<PlayerSelector
playerCount={4}
setPlayerCount={setPlayerCount}
darkMode={false}
/>
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
);
fireEvent.press(getByRole("button", { name: "-" }));
@ -49,11 +37,7 @@ describe("PlayerSelector Component", () => {
it("does not increase player count beyond 8", () => {
const setPlayerCount = jest.fn();
const { getByRole } = render(
<PlayerSelector
playerCount={8}
setPlayerCount={setPlayerCount}
darkMode={false}
/>
<PlayerSelector playerCount={8} setPlayerCount={setPlayerCount} />
);
fireEvent.press(getByRole("button", { name: "+" }));
@ -63,11 +47,7 @@ describe("PlayerSelector Component", () => {
it("does not decrease player count below 2", () => {
const setPlayerCount = jest.fn();
const { getByRole } = render(
<PlayerSelector
playerCount={2}
setPlayerCount={setPlayerCount}
darkMode={false}
/>
<PlayerSelector playerCount={2} setPlayerCount={setPlayerCount} />
);
fireEvent.press(getByRole("button", { name: "-" }));

View File

@ -1,19 +1,25 @@
import React from "react";
import { Text, TouchableOpacity, StyleSheet } from "react-native";
import { COLORS } from "@/styles/styles";
import React, { useMemo } from "react";
import {
Text,
TouchableOpacity,
StyleSheet,
useColorScheme,
} from "react-native";
interface ButtonProps {
title: string;
onPress: () => void;
disabled?: boolean;
darkMode: boolean;
}
const Button: React.FC<ButtonProps> = ({
title,
onPress,
disabled,
darkMode,
}) => {
const Button: React.FC<ButtonProps> = ({ title, onPress, disabled }) => {
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
return (
<TouchableOpacity
onPress={onPress}
@ -21,18 +27,11 @@ const Button: React.FC<ButtonProps> = ({
accessibilityRole="button"
style={[
styles.button,
darkMode ? styles.darkButton : styles.lightButton,
{ backgroundColor: colors.PRIMARY },
disabled && styles.disabled,
]}
>
<Text
style={[
styles.buttonText,
darkMode ? styles.darkText : styles.lightText,
]}
>
{title}
</Text>
<Text style={[styles.buttonText, { color: colors.TEXT }]}>{title}</Text>
</TouchableOpacity>
);
};

View File

@ -1,52 +0,0 @@
import React, { ReactNode } from "react";
import {
SafeAreaView,
StatusBar,
View,
StyleSheet,
Dimensions,
} from "react-native";
interface PokerAppUiProps {
children: ReactNode;
darkMode?: boolean;
}
const PokerAppUi: React.FC<PokerAppUiProps> = ({
children,
darkMode = false,
}) => {
const screenHeight = Dimensions.get("window").height;
return (
<SafeAreaView
style={[styles.safeArea, darkMode ? styles.lightGray : styles.light]}
>
<StatusBar barStyle={"dark-content"} />
<View style={[styles.container, { minHeight: screenHeight }]}>
{children}
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
safeArea: {
flex: 1,
},
container: {
flex: 1,
width: "100%",
padding: 16,
justifyContent: "flex-start",
alignItems: "center",
},
light: {
backgroundColor: "#F5F5F5",
},
lightGray: {
backgroundColor: "#D3D3D3",
},
});
export default PokerAppUi;

View File

@ -1,7 +1,7 @@
import { View, Text, StyleSheet } from "react-native";
import React from "react";
import { View, Text, StyleSheet, useColorScheme } from "react-native";
import React, { useMemo } from "react";
import { MaterialIcons } from "@expo/vector-icons";
import globalStyles from "@/styles/styles";
import globalStyles, { COLORS } from "@/styles/styles";
const titleCase = (input: string) =>
input
@ -23,6 +23,12 @@ const Section = ({
orientation?: "row" | "column";
contentStyle?: object;
}) => {
const colorScheme = useColorScheme();
const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]);
const colors = useMemo(
() => (darkMode ? COLORS.DARK : COLORS.LIGHT),
[darkMode]
);
return (
<View style={styles.container}>
<View style={styles.header}>
@ -30,9 +36,11 @@ const Section = ({
style={styles.icon}
name={iconName}
size={30}
color={"black"}
color={colors.TEXT}
/>
<Text style={styles.title}>{titleCase(title)}</Text>
<Text style={[styles.title, { color: colors.TEXT }]}>
{titleCase(title)}
</Text>
</View>
<View
style={{

View File

@ -48,7 +48,7 @@
"please_select_valid_buyin": "Please select a valid buy-in amount",
"chip_value_warn": "Be advised that the value of the distributed chips does not equal the buy-in for these inputs.\n\nHowever, results shown are fair to all players",
"appearance": "Appearance",
"switch_to_gray_mode": "Switch to Gray Mode",
"switch_to_dark_mode": "Switch to Dark Mode",
"switch_to_light_mode": "Switch to Light Mode"
}
}

View File

@ -49,7 +49,7 @@
"please_select_valid_buyin": "Por favor seleccione una cantidad de buy-in válida",
"chip_value_warn": "Tenga en cuenta que el valor de las fichas distribuidas no es igual al buy-in para estas entradas.\n\nSin embargo, los resultados que se muestran son justos para todos los jugadores.",
"appearance": "Apariencia",
"switch_to_gray_mode": "Cambiar a Modo Gris",
"switch_to_dark_mode": "Cambiar a Modo Oscuro",
"switch_to_light_mode": "Cambiar a Modo Claro"
}
}

View File

@ -1,16 +1,23 @@
import { StyleSheet } from "react-native";
export const COLORS = {
PRIMARY: "#007bff",
SECONDARY: "#6c757d",
SUCCESS: "#28a745",
DANGER: "#dc3545",
WARNING: "#c79c28",
LIGHT: {
TEXT: "black",
PRIMARY: "lightgrey",
SECONDARY: "azure",
BACKGROUND: "ghostwhite",
DISABLED: "gray",
},
DARK: {
TEXT: "white",
PRIMARY: "black",
SECONDARY: "teal",
BACKGROUND: "dimgrey",
DISABLED: "gray",
},
};
const lightStyles = StyleSheet.create({});
const darkStyles = StyleSheet.create({});
const GlobalStyles = StyleSheet.create({
scrollView: {},
scrollViewContent: {
@ -51,9 +58,11 @@ const GlobalStyles = StyleSheet.create({
textShadowRadius: 10,
},
picker: {
height: 50,
borderRadius: 10,
height: 55,
width: 150,
},
pickerItem: {},
});
export default GlobalStyles;