Skip to content

Commit 8c1f534

Browse files
feat: wip app mode switch updates
1 parent ede644a commit 8c1f534

8 files changed

Lines changed: 131 additions & 12 deletions

File tree

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import { Redirect } from "expo-router";
1+
import { Redirect, Stack } from "expo-router";
22
import React from "react";
3+
import { useCitizenUserData } from "../../../contexts/citizen-user/CitizenUserContext.provider";
34

45
export default function MainLayout() {
56
console.log("MainLayout");
67

7-
const selectedElectionRound = false;
8+
const { selectedElectionRound } = useCitizenUserData();
9+
10+
console.log("👀 selectedElectionRound", selectedElectionRound);
811

912
if (!selectedElectionRound) {
1013
return <Redirect href="/election-rounds" />;
1114
}
1215

13-
return <></>;
16+
return (
17+
<Stack>
18+
<Stack.Screen name="(drawer)" options={{ headerShown: false }} />
19+
<Stack.Screen name="questionnaire" options={{ headerShown: false }} />
20+
</Stack>
21+
);
1422
}

mobile/app/(citizen)/_layout.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
import { Slot } from "expo-router";
1+
import { Stack } from "expo-router";
22
import React from "react";
3+
import CitizenUserContextProvider from "../../contexts/citizen-user/CitizenUserContext.provider";
34

45
const CitizenLayout = () => {
56
console.log("CitizenLayout");
6-
return <Slot />;
7+
8+
return (
9+
<CitizenUserContextProvider>
10+
<Stack screenOptions={{ headerShown: false }}>
11+
<Stack.Screen name="(main)" />
12+
</Stack>
13+
</CitizenUserContextProvider>
14+
);
715
};
816

917
export default CitizenLayout;

mobile/app/(citizen)/election-rounds.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ import { Text } from "react-native";
22
import React from "react";
33
import Button from "../../components/Button";
44
import { Screen } from "../../components/Screen";
5+
import { useCitizenUserData } from "../../contexts/citizen-user/CitizenUserContext.provider";
56
import { router } from "expo-router";
67

78
function CitizenElectionRoundsSelector() {
9+
const { setSelectedElectionRound } = useCitizenUserData();
10+
811
return (
912
<Screen preset="fixed" contentContainerStyle={{ flexGrow: 1 }}>
10-
<Text>More Index </Text>
13+
<Text>Election Rounds</Text>
1114
<Button
1215
onPress={() => {
13-
router.replace("(main)");
16+
setSelectedElectionRound(true);
17+
router.push("(main)");
1418
}}
1519
>
1620
Du-te-n mm

mobile/app/_layout.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { isRunningInExpoGo } from "expo";
1616
import Toast from "react-native-toast-message";
1717
import { toastConfig } from "../toast.config";
1818
import * as Notifications from "expo-notifications";
19+
import AppModeContextProvider from "../contexts/app-mode/AppModeContext.provider";
1920

2021
// Construct a new instrumentation instance. This is needed to communicate between the integration and React
2122
const routingInstrumentation = new Sentry.ReactNavigationInstrumentation();
@@ -41,7 +42,7 @@ Sentry.init({
4142
enableNative: true,
4243
environment: process.env.EXPO_PUBLIC_ENVIRONMENT,
4344
attachScreenshot: true,
44-
enabled: !__DEV__,
45+
enabled: false,
4546
// Set tracesSampleRate to 1.0 to capture 100%
4647
// of transactions for performance monitoring.
4748
// We recommend adjusting this value in production
@@ -59,6 +60,7 @@ Sentry.init({
5960
SplashScreen.preventAutoHideAsync();
6061

6162
function RootLayout() {
63+
console.log("RootLayout");
6264
const [loaded] = useFonts({
6365
Roboto: require("../assets/fonts/Roboto-Medium.ttf"),
6466
RobotoRegular: require("../assets/fonts/Roboto-Regular.ttf"),
@@ -95,9 +97,11 @@ function RootLayout() {
9597
<PortalProvider>
9698
<LanguageContextProvider>
9799
<EasUpdateMonitorContextProvider>
98-
<Slot />
99-
<Toast config={toastConfig} position="top" />
100-
<NetInfoBanner />
100+
<AppModeContextProvider>
101+
<Slot />
102+
<Toast config={toastConfig} position="top" />
103+
<NetInfoBanner />
104+
</AppModeContextProvider>
101105
</EasUpdateMonitorContextProvider>
102106
</LanguageContextProvider>
103107
</PortalProvider>

mobile/app/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
import React from "react";
1+
import React, { useEffect } from "react";
22
import { Redirect } from "expo-router";
3+
import * as SecureStore from "expo-secure-store";
4+
import { SECURE_STORAGE_KEYS } from "../common/constants";
35

46
function AppModeWrapper() {
57
console.log("AppModeWrapper");
68
const APP_MODE = "citizen";
79

10+
useEffect(() => {
11+
try {
12+
const onboardingComplete = SecureStore.getItem(SECURE_STORAGE_KEYS.ONBOARDING_NEW_COMPLETE);
13+
if (onboardingComplete !== "true") {
14+
// setOnboardingComplete(false);
15+
}
16+
} catch (err) {
17+
// Sentry.captureException(err);
18+
}
19+
}, []);
20+
821
// 1. Redirect to onboarding if not already done // TODO: add another onboarding key
922
// 2. Redirect to citizen or app based on last OnBoarding step (Select AppMode)
1023
// 2.1. The last selection will be added in a context and here will take care of redirecting so we can do it declaratively

mobile/common/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const ASYNC_STORAGE_KEYS = {
66

77
export const SECURE_STORAGE_KEYS = {
88
ONBOARDING_COMPLETE: "onboardingComplete",
9+
ONBOARDING_NEW_COMPLETE: "onboardingNewComplete",
910
};
1011

1112
export const I18N_LANGUAGE = "i18n-language";
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { createContext, useState, useContext } from "react";
2+
3+
type AppModeContextType = {
4+
appMode?: "citizen" | "observer";
5+
setAppMode: (appMode: "citizen" | "observer") => void;
6+
7+
onboardingComplete: boolean;
8+
setOnboardingComplete: (onboardingComplete: boolean) => void;
9+
};
10+
11+
export const AppModeContext = createContext<AppModeContextType | null>(null);
12+
13+
const AppModeContextProvider = ({ children }: React.PropsWithChildren) => {
14+
const [appMode, setAppMode] = useState<"citizen" | "observer">();
15+
const [onboardingComplete, setOnboardingComplete] = useState<boolean>(false);
16+
17+
return (
18+
<AppModeContext.Provider
19+
value={{ appMode, setAppMode, onboardingComplete, setOnboardingComplete }}
20+
>
21+
{children}
22+
</AppModeContext.Provider>
23+
);
24+
};
25+
26+
export const useAppMode = () => {
27+
const data = useContext(AppModeContext);
28+
29+
if (!data) {
30+
throw new Error("No data in AppModeContext found. Was used outside the tree");
31+
}
32+
33+
return data;
34+
};
35+
36+
export default AppModeContextProvider;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { createContext, useContext, useEffect, useState } from "react";
2+
3+
type CitizenUserContextType = {
4+
selectedElectionRound: boolean;
5+
setSelectedElectionRound: (electionRound: boolean) => void;
6+
7+
// electionRounds: ElectionRoundVM[] | undefined;
8+
// visits: PollingStationVisitVM[] | undefined;
9+
10+
// activeElectionRound?: ElectionRoundVM;
11+
// selectedPollingStation?: PollingStationNomenclatorNodeVM | null;
12+
13+
// isLoading: boolean;
14+
15+
// error: Error | null;
16+
// setSelectedPollingStationId: (pollingStationId: string | null) => void;
17+
};
18+
19+
export const CitizenUserContext = createContext<CitizenUserContextType | null>(null);
20+
21+
const CitizenUserContextProvider = ({ children }: React.PropsWithChildren) => {
22+
const [selectedElectionRound, setSelectedElectionRound] = useState<boolean>(false);
23+
24+
useEffect(() => {
25+
console.log("👀 [Context] selectedElectionRound", selectedElectionRound);
26+
}, [selectedElectionRound]);
27+
28+
return (
29+
<CitizenUserContext.Provider value={{ selectedElectionRound, setSelectedElectionRound }}>
30+
{children}
31+
</CitizenUserContext.Provider>
32+
);
33+
};
34+
35+
export const useCitizenUserData = () => {
36+
const data = useContext(CitizenUserContext);
37+
38+
if (!data) {
39+
throw new Error("No data in CitizenUserContext found. Was used outside the tree");
40+
}
41+
42+
return data;
43+
};
44+
45+
export default CitizenUserContextProvider;

0 commit comments

Comments
 (0)