Files
SheetHappens/app/onboarding.tsx
T

141 lines
3.9 KiB
TypeScript

import { useState } from "react";
import { View, Text, Pressable, SafeAreaView } from "react-native";
import * as SecureStore from "expo-secure-store";
import { router } from "expo-router";
import { Colors } from "@/constants/theme";
const STEPS = [
{
key: "homeView",
question: "When you open the app…",
options: [
{ value: "dashboard", label: "Show recent incidents", desc: "Dashboard with the last 10 events" },
{ value: "capture", label: "Go straight to capture", desc: "New incident form opens immediately" },
],
},
{
key: "inputMode",
question: "How do you prefer to input incidents?",
options: [
{ value: "form", label: "Typed form", desc: "Fill in each field manually" },
{ value: "voice", label: "Voice dictation", desc: "Speak and let the app transcribe" },
],
},
{
key: "gitea",
question: "Do you want to push incidents to Gitea?",
options: [
{ value: "later", label: "Configure later", desc: "Set it up in Settings anytime" },
{ value: "now", label: "Set up now", desc: "You'll be redirected to Settings" },
],
},
] as const;
export default function OnboardingScreen() {
const [step, setStep] = useState(0);
const [answers, setAnswers] = useState<Record<string, string>>({});
const current = STEPS[step];
async function choose(value: string) {
const next = { ...answers, [current.key]: value };
setAnswers(next);
if (step < STEPS.length - 1) {
setStep((s) => s + 1);
} else {
await SecureStore.setItemAsync("pref_home_view", next.homeView ?? "dashboard");
await SecureStore.setItemAsync("pref_input_mode", next.inputMode ?? "form");
await SecureStore.setItemAsync("onboarding_done", "true");
if (next.gitea === "now") {
router.replace("/settings");
} else {
router.replace("/");
}
}
}
const progress = ((step + 1) / STEPS.length) * 100;
return (
<SafeAreaView style={{ flex: 1, backgroundColor: Colors.bg }}>
<View style={{ flex: 1, padding: 24, justifyContent: "center" }}>
{/* Progress bar */}
<View
style={{
height: 3,
backgroundColor: Colors.border,
borderRadius: 2,
marginBottom: 48,
}}
>
<View
style={{
height: 3,
width: `${progress}%`,
backgroundColor: Colors.primary,
borderRadius: 2,
}}
/>
</View>
<Text
style={{
color: Colors.textDim,
fontSize: 12,
fontWeight: "700",
textTransform: "uppercase",
letterSpacing: 1,
marginBottom: 12,
}}
>
{step + 1} / {STEPS.length}
</Text>
<Text
style={{
color: Colors.text1,
fontSize: 26,
fontWeight: "700",
marginBottom: 32,
lineHeight: 34,
}}
>
{current.question}
</Text>
<View style={{ gap: 12 }}>
{current.options.map((opt) => (
<Pressable
key={opt.value}
onPress={() => choose(opt.value)}
style={{
backgroundColor: Colors.surface,
borderRadius: 12,
padding: 20,
borderWidth: 1,
borderColor: Colors.border,
}}
>
<Text
style={{
color: Colors.text1,
fontSize: 17,
fontWeight: "600",
marginBottom: 4,
}}
>
{opt.label}
</Text>
<Text style={{ color: Colors.text2, fontSize: 14 }}>
{opt.desc}
</Text>
</Pressable>
))}
</View>
</View>
</SafeAreaView>
);
}