Refactor settings to use stack to allow dark theme. Move theme to app reducer to allow persistence.

This commit is contained in:
Patrick Fic
2025-10-23 13:58:33 -07:00
parent f170192008
commit b1ee922066
15 changed files with 60 additions and 23 deletions

View File

@@ -1,5 +0,0 @@
import Settings from "../components/settings/settings";
export default function Tab() {
return <Settings />;
}

27
app/settings/_layout.tsx Normal file
View File

@@ -0,0 +1,27 @@
import { Stack, useRouter } from "expo-router";
export default function SettingsLayout() {
const router = useRouter();
return (
<Stack>
<Stack.Screen
name="index"
options={{
title: "Settings",
headerShown: false,
// headerSearchBarOptions: {
// placement: "automatic",
// placeholder: "Search",
// autoFocus: true,
// shouldShowHintSearchIcon: true,
// onChangeText: (event) => {
// router.setParams({
// globalSearch: event?.nativeEvent?.text,
// });
// },
// },
}}
/>
</Stack>
);
}

5
app/settings/index.tsx Normal file
View File

@@ -0,0 +1,5 @@
import Settings from "../../components/settings/settings";
export default function Tab() {
return <Settings />;
}

View File

@@ -107,7 +107,7 @@ function JobListItemComponent({ openImagePicker, item }) {
const styles = StyleSheet.create({
pressable: {
marginHorizontal: 12,
// marginHorizontal: 12,
marginVertical: 6,
},
outerShadow: {

View File

@@ -1,8 +1,8 @@
import { useQuery } from "@apollo/client";
import React from "react";
import { useTranslation } from "react-i18next";
import { FlatList, RefreshControl, Text, View } from "react-native";
import { ActivityIndicator, Button } from "react-native-paper";
import { FlatList, RefreshControl, View } from "react-native";
import { ActivityIndicator, Button, Text } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -48,7 +48,13 @@ export function JobListComponent({ bodyshop }) {
const jobs = data ? [...(data?.jobs || []), { id: "footer-spacer" }] : [];
return (
<SafeAreaView style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1, marginHorizontal: 12 }}>
<Text
variant="headlineMedium"
style={{ marginBottom: 12, fontWeight: "600" }}
>
Jobs
</Text>
<UploadProgress />
<FlatList
refreshControl={

View File

@@ -1,5 +1,5 @@
import { setTheme } from "@/redux/user/user.actions";
import { selectTheme } from "@/redux/user/user.selectors";
import { setTheme } from "@/redux/app/app.actions";
import { selectTheme } from "@/redux/app/app.selectors";
import React from "react";
import { SegmentedButtons } from "react-native-paper";
import { useDispatch, useSelector } from "react-redux";

View File

@@ -1,4 +1,4 @@
import { selectTheme } from "@/redux/user/user.selectors";
import { selectTheme } from "@/redux/app/app.selectors";
import { darkTheme, lightTheme } from "@/util/theme";
import { useColorScheme } from "react-native";
import { useSelector } from "react-redux";

View File

@@ -27,3 +27,8 @@ export const documentUploadFailure = (error) => ({
export const toggleDeleteAfterUpload = () => ({
type: AppActionTypes.TOGGLE_DLETE_AFTER_UPLOAD,
});
export const setTheme = (theme) => ({
type: AppActionTypes.SET_THEME,
payload: theme,
});

View File

@@ -6,6 +6,7 @@ const INITIAL_STATE = {
documentUploadInProgress: null,
documentUploadError: null,
deleteAfterUpload: false,
theme: "system",
};
const appReducer = (state = INITIAL_STATE, action) => {
@@ -43,6 +44,8 @@ const appReducer = (state = INITIAL_STATE, action) => {
...state,
deleteAfterUpload: !state.deleteAfterUpload,
};
case AppActionTypes.SET_THEME:
return { ...state, theme: action.payload };
default:
return state;
}

View File

@@ -26,3 +26,8 @@ export const selectDeleteAfterUpload = createSelector(
[selectApp],
(app) => app.deleteAfterUpload
);
export const selectTheme = createSelector(
[selectApp],
(app) => app.theme
);

View File

@@ -5,5 +5,6 @@ const AppActionTypes = {
DOCUMENT_UPLOAD_SUCCESS: "DOCUMENT_UPLOAD_SUCCESS",
DOCUMENT_UPLOAD_FAILURE: "DOCUMENT_UPLOAD_FAILURE",
TOGGLE_DLETE_AFTER_UPLOAD: "TOGGLE_DLETE_AFTER_UPLOAD",
SET_THEME: "SET_THEME",
};
export default AppActionTypes;

View File

@@ -98,7 +98,3 @@ export const validatePasswordResetFailure = (error) => ({
type: UserActionTypes.VALIDATE_PASSWORD_RESET_FAILURE,
payload: error,
});
export const setTheme = (theme) => ({
type: UserActionTypes.SET_THEME,
payload: theme,
});

View File

@@ -49,8 +49,7 @@ const userReducer = (state = INITIAL_STATE, action) => {
case UserActionTypes.SET_SHOP_DETAILS:
return { ...state, bodyshop: action.payload };
case UserActionTypes.SET_THEME:
return { ...state, theme: action.payload };
case UserActionTypes.SIGN_IN_FAILURE:
case UserActionTypes.SIGN_OUT_FAILURE:
case UserActionTypes.EMAIL_SIGN_UP_FAILURE:

View File

@@ -32,7 +32,3 @@ export const selectSigningIn = createSelector(
(user) => user.signingIn
);
export const selectTheme = createSelector(
[selectUser],
(user) => user.theme
);

View File

@@ -26,6 +26,5 @@ const UserActionTypes = {
VALIDATE_PASSWORD_RESET_START: "VALIDATE_PASSWORD_RESET_START",
VALIDATE_PASSWORD_RESET_SUCCESS: "VALIDATE_PASSWORD_RESET_SUCCESS",
VALIDATE_PASSWORD_RESET_FAILURE: "VALIDATE_PASSWORD_RESET_FAILURE",
SET_THEME: "SET_THEME",
};
export default UserActionTypes;