299 lines
7.1 KiB
TypeScript
299 lines
7.1 KiB
TypeScript
/*
|
||
* File: SettingsItemComponent.tsx
|
||
* Description: Settings item component displaying individual settings options
|
||
* Design & Developed by Tech4Biz Solutions
|
||
* Copyright (c) Spurrin Innovations. All rights reserved.
|
||
*/
|
||
|
||
import React from 'react';
|
||
import { View, Text, StyleSheet, TouchableOpacity, Switch } from 'react-native';
|
||
import { theme } from '../../../theme/theme';
|
||
import { SettingsItem } from '../../../shared/types';
|
||
import Icon from 'react-native-vector-icons/Feather';
|
||
/**
|
||
* SettingsItemComponentProps Interface
|
||
*
|
||
* Purpose: Defines the props required by the SettingsItemComponent
|
||
*
|
||
* Props:
|
||
* - item: Settings item data to display
|
||
* - isLast: Boolean indicating if this is the last item in the section
|
||
*/
|
||
interface SettingsItemComponentProps {
|
||
item: SettingsItem;
|
||
isLast: boolean;
|
||
}
|
||
|
||
/**
|
||
* SettingsItemComponent Component
|
||
*
|
||
* Purpose: Displays individual settings items with different interaction types
|
||
*
|
||
* Features:
|
||
* - Navigation items with chevron
|
||
* - Toggle items with switch
|
||
* - Action items with custom styling
|
||
* - Icon support (placeholder)
|
||
* - Consistent styling and spacing
|
||
*/
|
||
export const SettingsItemComponent: React.FC<SettingsItemComponentProps> = ({ item, isLast }) => {
|
||
/**
|
||
* renderIcon Function
|
||
*
|
||
* Purpose: Render icon for the settings item
|
||
*
|
||
* @returns Icon component or placeholder
|
||
*/
|
||
const renderIcon = () => {
|
||
// TODO: Implement actual icon rendering
|
||
return (
|
||
<View style={styles.iconPlaceholder}>
|
||
<Icon name={item.icon} size={24} color={theme.colors.textPrimary} />
|
||
</View>
|
||
);
|
||
};
|
||
|
||
/**
|
||
* renderValue Function
|
||
*
|
||
* Purpose: Render the value/action component based on item type
|
||
*
|
||
* @returns Value component (switch, chevron, or custom)
|
||
*/
|
||
const renderValue = () => {
|
||
switch (item.type) {
|
||
case 'TOGGLE':
|
||
return (
|
||
<Switch
|
||
value={item.value || false}
|
||
onValueChange={item.onPress}
|
||
trackColor={{ false: theme.colors.border, true: theme.colors.primary }}
|
||
thumbColor={theme.colors.background}
|
||
ios_backgroundColor={theme.colors.border}
|
||
/>
|
||
);
|
||
|
||
case 'NAVIGATION':
|
||
return (
|
||
<Text style={styles.chevron}>›</Text>
|
||
);
|
||
|
||
case 'ACTION':
|
||
return (
|
||
<Text style={styles.actionText}>Sign Out</Text>
|
||
);
|
||
|
||
default:
|
||
return null;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* getItemStyle Function
|
||
*
|
||
* Purpose: Get appropriate styling based on item type and position
|
||
*
|
||
* @returns Style object for the item container
|
||
*/
|
||
const getItemStyle = () => {
|
||
const baseStyle = [styles.container];
|
||
|
||
// Add border bottom if not the last item
|
||
if (!isLast) {
|
||
baseStyle.push(styles.withBorder);
|
||
}
|
||
|
||
// Add special styling for action items
|
||
if (item.type === 'ACTION') {
|
||
baseStyle.push(styles.actionItem);
|
||
}
|
||
|
||
// Add disabled styling if item is disabled
|
||
if (item.disabled) {
|
||
baseStyle.push(styles.disabledItem);
|
||
}
|
||
|
||
return baseStyle;
|
||
};
|
||
|
||
/**
|
||
* getTextStyle Function
|
||
*
|
||
* Purpose: Get appropriate text styling based on item state
|
||
*
|
||
* @returns Style object for text
|
||
*/
|
||
const getTextStyle = () => {
|
||
if (item.disabled) {
|
||
return [styles.title, styles.disabledText];
|
||
}
|
||
if (item.type === 'ACTION') {
|
||
return [styles.title, styles.actionTitle];
|
||
}
|
||
return styles.title;
|
||
};
|
||
|
||
/**
|
||
* getSubtitleStyle Function
|
||
*
|
||
* Purpose: Get appropriate subtitle styling based on item state
|
||
*
|
||
* @returns Style object for subtitle
|
||
*/
|
||
const getSubtitleStyle = () => {
|
||
if (item.disabled) {
|
||
return [styles.subtitle, styles.disabledText];
|
||
}
|
||
return styles.subtitle;
|
||
};
|
||
|
||
return (
|
||
<TouchableOpacity
|
||
style={getItemStyle()}
|
||
onPress={item.onPress}
|
||
disabled={item.disabled}
|
||
activeOpacity={0.7}
|
||
>
|
||
{/* Icon */}
|
||
{renderIcon()}
|
||
|
||
{/* Content */}
|
||
<View style={styles.content}>
|
||
<View style={styles.textContainer}>
|
||
<Text style={getTextStyle()}>{item.title}</Text>
|
||
{item.subtitle && (
|
||
<Text style={getSubtitleStyle()}>{item.subtitle}</Text>
|
||
)}
|
||
</View>
|
||
|
||
{/* Badge */}
|
||
{item.badge && (
|
||
<View style={styles.badge}>
|
||
<Text style={styles.badgeText}>{item.badge}</Text>
|
||
</View>
|
||
)}
|
||
</View>
|
||
|
||
{/* Value/Action */}
|
||
{renderValue()}
|
||
</TouchableOpacity>
|
||
);
|
||
};
|
||
|
||
// ============================================================================
|
||
// STYLES SECTION
|
||
// ============================================================================
|
||
|
||
const styles = StyleSheet.create({
|
||
// Main container for the settings item
|
||
container: {
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
paddingHorizontal: theme.spacing.md,
|
||
paddingVertical: theme.spacing.md,
|
||
backgroundColor: theme.colors.background,
|
||
borderRadius: theme.borderRadius.medium,
|
||
},
|
||
|
||
// Container with bottom border
|
||
withBorder: {
|
||
borderBottomColor: theme.colors.border,
|
||
borderBottomWidth: 1,
|
||
},
|
||
|
||
// Action item styling
|
||
actionItem: {
|
||
backgroundColor: theme.colors.background,
|
||
},
|
||
|
||
// Disabled item styling
|
||
disabledItem: {
|
||
opacity: 0.5,
|
||
},
|
||
|
||
// Icon placeholder styling
|
||
iconPlaceholder: {
|
||
width: 24,
|
||
height: 24,
|
||
marginRight: theme.spacing.md,
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
},
|
||
|
||
// Icon text styling
|
||
iconText: {
|
||
fontSize: 16,
|
||
},
|
||
|
||
// Content container
|
||
content: {
|
||
flex: 1,
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
},
|
||
|
||
// Text container
|
||
textContainer: {
|
||
flex: 1,
|
||
},
|
||
|
||
// Title text styling
|
||
title: {
|
||
fontSize: theme.typography.fontSize.bodyMedium,
|
||
fontFamily: theme.typography.fontFamily.medium,
|
||
color: theme.colors.textPrimary,
|
||
marginBottom: theme.spacing.xs,
|
||
},
|
||
|
||
// Action title styling
|
||
actionTitle: {
|
||
color: theme.colors.error,
|
||
},
|
||
|
||
// Subtitle text styling
|
||
subtitle: {
|
||
fontSize: theme.typography.fontSize.bodySmall,
|
||
color: theme.colors.textSecondary,
|
||
},
|
||
|
||
// Disabled text styling
|
||
disabledText: {
|
||
color: theme.colors.textMuted,
|
||
},
|
||
|
||
// Badge styling
|
||
badge: {
|
||
backgroundColor: theme.colors.primary,
|
||
borderRadius: theme.borderRadius.small,
|
||
paddingHorizontal: theme.spacing.sm,
|
||
paddingVertical: theme.spacing.xs,
|
||
marginLeft: theme.spacing.sm,
|
||
},
|
||
|
||
// Badge text styling
|
||
badgeText: {
|
||
fontSize: theme.typography.fontSize.caption,
|
||
fontFamily: theme.typography.fontFamily.medium,
|
||
color: theme.colors.background,
|
||
},
|
||
|
||
// Chevron styling for navigation items
|
||
chevron: {
|
||
fontSize: theme.typography.fontSize.bodyLarge,
|
||
color: theme.colors.textMuted,
|
||
fontFamily: theme.typography.fontFamily.bold,
|
||
},
|
||
|
||
// Action text styling
|
||
actionText: {
|
||
fontSize: theme.typography.fontSize.bodyMedium,
|
||
fontFamily: theme.typography.fontFamily.medium,
|
||
color: theme.colors.error,
|
||
},
|
||
});
|
||
|
||
/*
|
||
* End of File: SettingsItemComponent.tsx
|
||
* Design & Developed by Tech4Biz Solutions
|
||
* Copyright (c) Spurrin Innovations. All rights reserved.
|
||
*/
|