refactor(app): restructure settings with modular section navigation

This commit is contained in:
Mohamed Boudra
2026-04-18 14:21:40 +07:00
parent 63a46acaf1
commit 5c3cc99d8c
41 changed files with 2526 additions and 2317 deletions
@@ -0,0 +1,90 @@
import { Pressable, Text, View } from "react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import type { LucideIcon } from "lucide-react-native";
import { HEADER_INNER_HEIGHT, HEADER_INNER_HEIGHT_MOBILE } from "@/constants/layout";
interface SidebarHeaderRowProps {
icon: LucideIcon;
label: string;
onPress: () => void;
isActive?: boolean;
testID?: string;
nativeID?: string;
accessibilityLabel?: string;
}
/**
* Top-of-sidebar header row: a sidebar-height pressable with an icon + label
* and a full-width border separator beneath. Used as the first element of a
* sidebar (workspace "Sessions", settings "Back to workspace"). Owns its own
* separator line so both sidebars converge on the same edge and padding.
*/
export function SidebarHeaderRow({
icon: Icon,
label,
onPress,
isActive = false,
testID,
nativeID,
accessibilityLabel,
}: SidebarHeaderRowProps) {
const { theme } = useUnistyles();
return (
<View style={styles.container}>
<Pressable
onPress={onPress}
testID={testID}
nativeID={nativeID}
accessible
accessibilityRole="button"
accessibilityLabel={accessibilityLabel ?? label}
style={({ hovered }) => [styles.button, (hovered || isActive) && styles.buttonHovered]}
>
{({ hovered }) => {
const isHighlighted = hovered || isActive;
const iconColor = isHighlighted ? theme.colors.foreground : theme.colors.foregroundMuted;
return (
<>
<Icon size={theme.iconSize.md} color={iconColor} />
<Text style={[styles.label, isHighlighted && styles.labelHighlighted]}>{label}</Text>
</>
);
}}
</Pressable>
</View>
);
}
const styles = StyleSheet.create((theme) => ({
container: {
height: {
xs: HEADER_INNER_HEIGHT_MOBILE,
md: HEADER_INNER_HEIGHT,
},
paddingHorizontal: theme.spacing[2],
justifyContent: "center",
borderBottomWidth: 1,
borderBottomColor: theme.colors.border,
userSelect: "none",
},
button: {
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[2],
paddingVertical: theme.spacing[2],
paddingHorizontal: theme.spacing[3],
borderRadius: theme.borderRadius.lg,
},
buttonHovered: {
backgroundColor: theme.colors.surfaceSidebarHover,
},
label: {
fontSize: theme.fontSize.base,
fontWeight: theme.fontWeight.normal,
color: theme.colors.foregroundMuted,
},
labelHighlighted: {
color: theme.colors.foreground,
},
}));
@@ -0,0 +1,18 @@
import { View } from "react-native";
import { StyleSheet } from "react-native-unistyles";
/**
* Edge-to-edge separator line for sidebars. Must render outside any horizontally
* padded container so the line runs the full sidebar width — matching the
* separator beneath the workspace sidebar's "New agent" header.
*/
export function SidebarSeparator() {
return <View style={styles.line} />;
}
const styles = StyleSheet.create((theme) => ({
line: {
borderBottomWidth: 1,
borderBottomColor: theme.colors.border,
},
}));