summaryrefslogblamecommitdiff
path: root/apps/mobile/app/(tabs)/settings.tsx
blob: f90e86c703554fb9b1bb2cfac2d8a892df7c4dc6 (plain) (tree)























































































































































































































































                                                                                    
import React, { useCallback } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  useColorScheme,
  Alert,
  Linking,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { Colors } from '../../constants/Colors';
import { getEnvironment } from '../../lib/api';
import { useAuthStore } from '../../stores/authStore';
import { config } from '../../lib/config';

interface SettingsRowProps {
  icon: keyof typeof Ionicons.glyphMap;
  title: string;
  value?: string;
  onPress?: () => void;
  showChevron?: boolean;
}

function SettingsRow({
  icon,
  title,
  value,
  onPress,
  showChevron = true,
}: SettingsRowProps) {
  const colorScheme = useColorScheme() ?? 'light';
  const colors = Colors[colorScheme];

  const content = (
    <View style={[styles.row, { borderBottomColor: colors.border }]}>
      <View style={[styles.iconContainer, { backgroundColor: colors.tint + '20' }]}>
        <Ionicons name={icon} size={20} color={colors.tint} />
      </View>
      <Text style={[styles.rowTitle, { color: colors.text }]}>{title}</Text>
      {value && (
        <Text style={[styles.rowValue, { color: colors.secondaryText }]}>
          {value}
        </Text>
      )}
      {showChevron && onPress && (
        <Ionicons name="chevron-forward" size={20} color={colors.secondaryText} />
      )}
    </View>
  );

  if (onPress) {
    return (
      <TouchableOpacity onPress={onPress} activeOpacity={0.7}>
        {content}
      </TouchableOpacity>
    );
  }

  return content;
}

export default function SettingsScreen() {
  const colorScheme = useColorScheme() ?? 'light';
  const colors = Colors[colorScheme];
  const signOut = useAuthStore((state) => state.signOut);
  const isLoading = useAuthStore((state) => state.isLoading);

  const environment = getEnvironment();

  const handleSignOut = useCallback(() => {
    Alert.alert(
      'Sign Out',
      'Are you sure you want to sign out?',
      [
        { text: 'Cancel', style: 'cancel' },
        {
          text: 'Sign Out',
          style: 'destructive',
          onPress: () => signOut(),
        },
      ]
    );
  }, [signOut]);

  const handleOpenUrl = useCallback((url: string) => {
    Linking.openURL(url);
  }, []);

  return (
    <ScrollView
      style={[styles.container, { backgroundColor: colors.background }]}
      contentContainerStyle={styles.content}
    >
      {/* Account Section */}
      <View style={styles.section}>
        <Text style={[styles.sectionTitle, { color: colors.secondaryText }]}>
          Account
        </Text>
        <View style={[styles.card, { backgroundColor: colors.card }]}>
          <SettingsRow
            icon="person-outline"
            title="Profile"
            onPress={() => {}}
          />
          <SettingsRow
            icon="notifications-outline"
            title="Notifications"
            onPress={() => {}}
          />
          <SettingsRow
            icon="key-outline"
            title="API Key"
            onPress={() => {}}
          />
        </View>
      </View>

      {/* App Section */}
      <View style={styles.section}>
        <Text style={[styles.sectionTitle, { color: colors.secondaryText }]}>
          App
        </Text>
        <View style={[styles.card, { backgroundColor: colors.card }]}>
          <SettingsRow
            icon="color-palette-outline"
            title="Appearance"
            value={colorScheme === 'dark' ? 'Dark' : 'Light'}
            showChevron={false}
          />
          <SettingsRow
            icon="server-outline"
            title="Environment"
            value={environment === 'local' ? 'Local' : 'Production'}
            showChevron={false}
          />
        </View>
      </View>

      {/* Support Section */}
      <View style={styles.section}>
        <Text style={[styles.sectionTitle, { color: colors.secondaryText }]}>
          Support
        </Text>
        <View style={[styles.card, { backgroundColor: colors.card }]}>
          <SettingsRow
            icon="help-circle-outline"
            title="Help & Support"
            onPress={() => handleOpenUrl(config.supportUrl)}
          />
          <SettingsRow
            icon="document-text-outline"
            title="Terms of Service"
            onPress={() => handleOpenUrl(config.termsOfServiceUrl)}
          />
          <SettingsRow
            icon="shield-checkmark-outline"
            title="Privacy Policy"
            onPress={() => handleOpenUrl(config.privacyPolicyUrl)}
          />
        </View>
      </View>

      {/* Sign Out */}
      <View style={styles.section}>
        <TouchableOpacity
          style={[styles.signOutButton, { backgroundColor: colors.card }]}
          onPress={handleSignOut}
          activeOpacity={0.7}
          disabled={isLoading}
        >
          <Ionicons name="log-out-outline" size={20} color="#ef4444" />
          <Text style={styles.signOutText}>Sign Out</Text>
        </TouchableOpacity>
      </View>

      {/* Version */}
      <Text style={[styles.version, { color: colors.secondaryText }]}>
        Makima Mobile v1.0.0
      </Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    padding: 16,
    gap: 24,
  },
  section: {
    gap: 8,
  },
  sectionTitle: {
    fontSize: 13,
    fontWeight: '600',
    textTransform: 'uppercase',
    letterSpacing: 0.5,
    marginLeft: 16,
  },
  card: {
    borderRadius: 12,
    overflow: 'hidden',
  },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    paddingHorizontal: 16,
    borderBottomWidth: StyleSheet.hairlineWidth,
    gap: 12,
  },
  iconContainer: {
    width: 32,
    height: 32,
    borderRadius: 8,
    alignItems: 'center',
    justifyContent: 'center',
  },
  rowTitle: {
    flex: 1,
    fontSize: 16,
  },
  rowValue: {
    fontSize: 14,
  },
  signOutButton: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 16,
    borderRadius: 12,
    gap: 8,
  },
  signOutText: {
    fontSize: 16,
    fontWeight: '600',
    color: '#ef4444',
  },
  version: {
    textAlign: 'center',
    fontSize: 12,
    marginTop: 8,
  },
});