Add equipment status workflow to beneficiary cards
- BeneficiaryCard now shows equipment status badges (ordered/shipped/delivered) - Added AwaitingEquipmentScreen with progress tracker - "I received my kit" button to mark as delivered - "Activate" button when equipment is delivered - Fixed address field height in add-loved-one form 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7cb07c09ce
commit
2545aec485
@ -184,16 +184,14 @@ export default function AddLovedOneScreen() {
|
|||||||
|
|
||||||
<View style={styles.inputGroup}>
|
<View style={styles.inputGroup}>
|
||||||
<Text style={styles.inputLabel}>Address (optional)</Text>
|
<Text style={styles.inputLabel}>Address (optional)</Text>
|
||||||
<View style={[styles.inputContainer, styles.addressInput]}>
|
<View style={styles.inputContainer}>
|
||||||
<Ionicons name="location-outline" size={20} color={AppColors.textMuted} style={styles.addressIcon} />
|
<Ionicons name="location-outline" size={20} color={AppColors.textMuted} />
|
||||||
<TextInput
|
<TextInput
|
||||||
style={[styles.input, styles.addressTextInput]}
|
style={styles.input}
|
||||||
value={address}
|
value={address}
|
||||||
onChangeText={setAddress}
|
onChangeText={setAddress}
|
||||||
placeholder="123 Main St, City, State"
|
placeholder="123 Main St, City, State"
|
||||||
placeholderTextColor={AppColors.textMuted}
|
placeholderTextColor={AppColors.textMuted}
|
||||||
multiline
|
|
||||||
numberOfLines={2}
|
|
||||||
editable={!isLoading}
|
editable={!isLoading}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@ -327,16 +325,6 @@ const styles = StyleSheet.create({
|
|||||||
paddingVertical: Spacing.md,
|
paddingVertical: Spacing.md,
|
||||||
marginLeft: Spacing.sm,
|
marginLeft: Spacing.sm,
|
||||||
},
|
},
|
||||||
addressInput: {
|
|
||||||
alignItems: 'flex-start',
|
|
||||||
},
|
|
||||||
addressIcon: {
|
|
||||||
marginTop: Spacing.md,
|
|
||||||
},
|
|
||||||
addressTextInput: {
|
|
||||||
minHeight: 60,
|
|
||||||
textAlignVertical: 'top',
|
|
||||||
},
|
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
marginTop: Spacing.md,
|
marginTop: Spacing.md,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,7 +41,7 @@ const isLocalBeneficiary = (id: string | number): boolean => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup state types
|
// Setup state types
|
||||||
type SetupState = 'loading' | 'no_devices' | 'no_subscription' | 'ready';
|
type SetupState = 'loading' | 'awaiting_equipment' | 'no_devices' | 'no_subscription' | 'ready';
|
||||||
|
|
||||||
// No Devices Screen Component
|
// No Devices Screen Component
|
||||||
function NoDevicesScreen({
|
function NoDevicesScreen({
|
||||||
@ -162,6 +162,133 @@ function NoSubscriptionScreen({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equipment status configuration
|
||||||
|
const equipmentStatusInfo = {
|
||||||
|
ordered: {
|
||||||
|
icon: 'cube-outline' as const,
|
||||||
|
title: 'Kit Ordered',
|
||||||
|
subtitle: 'Your WellNuo kit is being prepared for shipping',
|
||||||
|
color: AppColors.info,
|
||||||
|
bgColor: AppColors.infoLight,
|
||||||
|
steps: [
|
||||||
|
{ label: 'Order placed', done: true },
|
||||||
|
{ label: 'Preparing', done: true },
|
||||||
|
{ label: 'Shipped', done: false },
|
||||||
|
{ label: 'Delivered', done: false },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
shipped: {
|
||||||
|
icon: 'car-outline' as const,
|
||||||
|
title: 'In Transit',
|
||||||
|
subtitle: 'Your WellNuo kit is on its way',
|
||||||
|
color: AppColors.warning,
|
||||||
|
bgColor: AppColors.warningLight,
|
||||||
|
steps: [
|
||||||
|
{ label: 'Order placed', done: true },
|
||||||
|
{ label: 'Preparing', done: true },
|
||||||
|
{ label: 'Shipped', done: true },
|
||||||
|
{ label: 'Delivered', done: false },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
delivered: {
|
||||||
|
icon: 'checkmark-circle-outline' as const,
|
||||||
|
title: 'Delivered',
|
||||||
|
subtitle: 'Your kit has arrived! Time to set it up.',
|
||||||
|
color: AppColors.success,
|
||||||
|
bgColor: AppColors.successLight,
|
||||||
|
steps: [
|
||||||
|
{ label: 'Order placed', done: true },
|
||||||
|
{ label: 'Preparing', done: true },
|
||||||
|
{ label: 'Shipped', done: true },
|
||||||
|
{ label: 'Delivered', done: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Awaiting Equipment Screen Component
|
||||||
|
function AwaitingEquipmentScreen({
|
||||||
|
beneficiary,
|
||||||
|
onActivate,
|
||||||
|
onMarkReceived,
|
||||||
|
}: {
|
||||||
|
beneficiary: Beneficiary;
|
||||||
|
onActivate: () => void;
|
||||||
|
onMarkReceived: () => void;
|
||||||
|
}) {
|
||||||
|
const status = beneficiary.equipmentStatus as 'ordered' | 'shipped' | 'delivered';
|
||||||
|
const info = equipmentStatusInfo[status] || equipmentStatusInfo.ordered;
|
||||||
|
const isDelivered = status === 'delivered';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.setupContainer}>
|
||||||
|
<View style={[styles.setupIconContainer, { backgroundColor: info.bgColor }]}>
|
||||||
|
<Ionicons name={info.icon} size={48} color={info.color} />
|
||||||
|
</View>
|
||||||
|
<Text style={styles.setupTitle}>{info.title}</Text>
|
||||||
|
<Text style={styles.setupSubtitle}>{info.subtitle}</Text>
|
||||||
|
|
||||||
|
{/* Progress steps */}
|
||||||
|
<View style={styles.progressContainer}>
|
||||||
|
{info.steps.map((step, index) => (
|
||||||
|
<View key={index} style={styles.progressStep}>
|
||||||
|
<View style={[
|
||||||
|
styles.progressDot,
|
||||||
|
step.done && styles.progressDotDone,
|
||||||
|
!step.done && styles.progressDotPending,
|
||||||
|
]}>
|
||||||
|
{step.done && (
|
||||||
|
<Ionicons name="checkmark" size={12} color={AppColors.white} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<Text style={[
|
||||||
|
styles.progressLabel,
|
||||||
|
step.done && styles.progressLabelDone,
|
||||||
|
]}>
|
||||||
|
{step.label}
|
||||||
|
</Text>
|
||||||
|
{index < info.steps.length - 1 && (
|
||||||
|
<View style={[
|
||||||
|
styles.progressLine,
|
||||||
|
step.done && styles.progressLineDone,
|
||||||
|
]} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Tracking number if available */}
|
||||||
|
{beneficiary.trackingNumber && (
|
||||||
|
<View style={styles.trackingCard}>
|
||||||
|
<Ionicons name="locate-outline" size={20} color={AppColors.textSecondary} />
|
||||||
|
<View style={styles.trackingInfo}>
|
||||||
|
<Text style={styles.trackingLabel}>Tracking Number</Text>
|
||||||
|
<Text style={styles.trackingNumber}>{beneficiary.trackingNumber}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Actions */}
|
||||||
|
<View style={styles.awaitingActions}>
|
||||||
|
{isDelivered ? (
|
||||||
|
<Button
|
||||||
|
title="Activate Sensors"
|
||||||
|
onPress={onActivate}
|
||||||
|
fullWidth
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<TouchableOpacity style={styles.receivedButton} onPress={onMarkReceived}>
|
||||||
|
<Ionicons name="checkmark-circle-outline" size={20} color={AppColors.primary} />
|
||||||
|
<Text style={styles.receivedButtonText}>I received my kit</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function BeneficiaryDetailScreen() {
|
export default function BeneficiaryDetailScreen() {
|
||||||
const { id } = useLocalSearchParams<{ id: string }>();
|
const { id } = useLocalSearchParams<{ id: string }>();
|
||||||
const { setCurrentBeneficiary, localBeneficiaries, updateLocalBeneficiary, removeLocalBeneficiary } = useBeneficiary();
|
const { setCurrentBeneficiary, localBeneficiaries, updateLocalBeneficiary, removeLocalBeneficiary } = useBeneficiary();
|
||||||
@ -178,6 +305,12 @@ export default function BeneficiaryDetailScreen() {
|
|||||||
if (isLoading) return 'loading';
|
if (isLoading) return 'loading';
|
||||||
if (!beneficiary) return 'loading';
|
if (!beneficiary) return 'loading';
|
||||||
|
|
||||||
|
// Check if awaiting equipment (ordered, shipped, or delivered but not activated)
|
||||||
|
const equipmentStatus = beneficiary.equipmentStatus;
|
||||||
|
if (equipmentStatus && ['ordered', 'shipped', 'delivered'].includes(equipmentStatus)) {
|
||||||
|
return 'awaiting_equipment';
|
||||||
|
}
|
||||||
|
|
||||||
// Check if has devices
|
// Check if has devices
|
||||||
const hasDevices = beneficiary.hasDevices ||
|
const hasDevices = beneficiary.hasDevices ||
|
||||||
(beneficiary.devices && beneficiary.devices.length > 0) ||
|
(beneficiary.devices && beneficiary.devices.length > 0) ||
|
||||||
@ -280,6 +413,31 @@ export default function BeneficiaryDetailScreen() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMarkReceived = async () => {
|
||||||
|
if (!beneficiary || !id) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Update local beneficiary status to delivered
|
||||||
|
if (isLocal) {
|
||||||
|
await updateLocalBeneficiary(parseInt(id, 10), {
|
||||||
|
equipmentStatus: 'delivered',
|
||||||
|
});
|
||||||
|
// Reload to refresh UI
|
||||||
|
loadBeneficiary(false);
|
||||||
|
}
|
||||||
|
// For API beneficiaries, would call backend here
|
||||||
|
} catch (err) {
|
||||||
|
Alert.alert('Error', 'Failed to update status');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleActivateFromStatus = () => {
|
||||||
|
router.push({
|
||||||
|
pathname: '/(auth)/activate',
|
||||||
|
params: { lovedOneName: beneficiary?.name, beneficiaryId: id },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleEditPress = () => {
|
const handleEditPress = () => {
|
||||||
if (beneficiary) {
|
if (beneficiary) {
|
||||||
setEditForm({
|
setEditForm({
|
||||||
@ -388,6 +546,15 @@ export default function BeneficiaryDetailScreen() {
|
|||||||
// Render based on setup state
|
// Render based on setup state
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
switch (setupState) {
|
switch (setupState) {
|
||||||
|
case 'awaiting_equipment':
|
||||||
|
return (
|
||||||
|
<AwaitingEquipmentScreen
|
||||||
|
beneficiary={beneficiary}
|
||||||
|
onActivate={handleActivateFromStatus}
|
||||||
|
onMarkReceived={handleMarkReceived}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
case 'no_devices':
|
case 'no_devices':
|
||||||
return (
|
return (
|
||||||
<NoDevicesScreen
|
<NoDevicesScreen
|
||||||
@ -810,6 +977,97 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
// Equipment Progress Styles
|
||||||
|
progressContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
marginBottom: Spacing.xl,
|
||||||
|
width: '100%',
|
||||||
|
paddingHorizontal: Spacing.md,
|
||||||
|
},
|
||||||
|
progressStep: {
|
||||||
|
alignItems: 'center',
|
||||||
|
flex: 1,
|
||||||
|
position: 'relative',
|
||||||
|
},
|
||||||
|
progressDot: {
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
borderRadius: 12,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: Spacing.xs,
|
||||||
|
},
|
||||||
|
progressDotDone: {
|
||||||
|
backgroundColor: AppColors.success,
|
||||||
|
},
|
||||||
|
progressDotPending: {
|
||||||
|
backgroundColor: AppColors.border,
|
||||||
|
},
|
||||||
|
progressLabel: {
|
||||||
|
fontSize: FontSizes.xs,
|
||||||
|
color: AppColors.textMuted,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
progressLabelDone: {
|
||||||
|
color: AppColors.textPrimary,
|
||||||
|
fontWeight: FontWeights.medium,
|
||||||
|
},
|
||||||
|
progressLine: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 12,
|
||||||
|
left: '50%',
|
||||||
|
right: '-50%',
|
||||||
|
height: 2,
|
||||||
|
backgroundColor: AppColors.border,
|
||||||
|
zIndex: -1,
|
||||||
|
},
|
||||||
|
progressLineDone: {
|
||||||
|
backgroundColor: AppColors.success,
|
||||||
|
},
|
||||||
|
trackingCard: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: AppColors.surface,
|
||||||
|
borderRadius: BorderRadius.lg,
|
||||||
|
padding: Spacing.md,
|
||||||
|
marginBottom: Spacing.lg,
|
||||||
|
width: '100%',
|
||||||
|
gap: Spacing.md,
|
||||||
|
...Shadows.sm,
|
||||||
|
},
|
||||||
|
trackingInfo: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
trackingLabel: {
|
||||||
|
fontSize: FontSizes.xs,
|
||||||
|
color: AppColors.textMuted,
|
||||||
|
},
|
||||||
|
trackingNumber: {
|
||||||
|
fontSize: FontSizes.base,
|
||||||
|
fontWeight: FontWeights.semibold,
|
||||||
|
color: AppColors.textPrimary,
|
||||||
|
},
|
||||||
|
awaitingActions: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
receivedButton: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: AppColors.surface,
|
||||||
|
borderRadius: BorderRadius.lg,
|
||||||
|
padding: Spacing.md,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: AppColors.primary,
|
||||||
|
gap: Spacing.sm,
|
||||||
|
},
|
||||||
|
receivedButtonText: {
|
||||||
|
fontSize: FontSizes.base,
|
||||||
|
fontWeight: FontWeights.semibold,
|
||||||
|
color: AppColors.primary,
|
||||||
|
},
|
||||||
// Subscription Price Card
|
// Subscription Price Card
|
||||||
subscriptionPriceCard: {
|
subscriptionPriceCard: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
@ -26,19 +26,59 @@ import {
|
|||||||
} from '@/constants/theme';
|
} from '@/constants/theme';
|
||||||
import type { Beneficiary } from '@/types';
|
import type { Beneficiary } from '@/types';
|
||||||
|
|
||||||
// Simplified beneficiary card: Avatar + Name + Warning (if no subscription)
|
// Beneficiary card with equipment status support
|
||||||
interface BeneficiaryCardProps {
|
interface BeneficiaryCardProps {
|
||||||
beneficiary: Beneficiary;
|
beneficiary: Beneficiary;
|
||||||
onPress: () => void;
|
onPress: () => void;
|
||||||
|
onActivate?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function BeneficiaryCard({ beneficiary, onPress }: BeneficiaryCardProps) {
|
// Equipment status config
|
||||||
// Check if subscription is missing or expired
|
const equipmentStatusConfig = {
|
||||||
const hasNoSubscription = !beneficiary.subscription ||
|
ordered: {
|
||||||
beneficiary.subscription.status !== 'active';
|
icon: 'cube-outline' as const,
|
||||||
|
label: 'Kit ordered',
|
||||||
|
sublabel: 'Preparing to ship',
|
||||||
|
color: AppColors.info,
|
||||||
|
bgColor: AppColors.infoLight,
|
||||||
|
},
|
||||||
|
shipped: {
|
||||||
|
icon: 'car-outline' as const,
|
||||||
|
label: 'In transit',
|
||||||
|
sublabel: 'Track your package',
|
||||||
|
color: AppColors.warning,
|
||||||
|
bgColor: AppColors.warningLight,
|
||||||
|
},
|
||||||
|
delivered: {
|
||||||
|
icon: 'checkmark-circle-outline' as const,
|
||||||
|
label: 'Delivered',
|
||||||
|
sublabel: 'Ready to activate',
|
||||||
|
color: AppColors.success,
|
||||||
|
bgColor: AppColors.successLight,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function BeneficiaryCard({ beneficiary, onPress, onActivate }: BeneficiaryCardProps) {
|
||||||
|
const equipmentStatus = beneficiary.equipmentStatus;
|
||||||
|
const isAwaitingEquipment = equipmentStatus && ['ordered', 'shipped', 'delivered'].includes(equipmentStatus);
|
||||||
|
const statusConfig = equipmentStatus ? equipmentStatusConfig[equipmentStatus as keyof typeof equipmentStatusConfig] : null;
|
||||||
|
|
||||||
|
// Check if subscription is missing or expired (only for active equipment)
|
||||||
|
const hasNoSubscription = !isAwaitingEquipment && (
|
||||||
|
!beneficiary.subscription || beneficiary.subscription.status !== 'active'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle press - if delivered, go to activate
|
||||||
|
const handlePress = () => {
|
||||||
|
if (equipmentStatus === 'delivered' && onActivate) {
|
||||||
|
onActivate();
|
||||||
|
} else {
|
||||||
|
onPress();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={styles.card} onPress={onPress} activeOpacity={0.7}>
|
<TouchableOpacity style={styles.card} onPress={handlePress} activeOpacity={0.7}>
|
||||||
{/* Avatar */}
|
{/* Avatar */}
|
||||||
<View style={styles.avatarWrapper}>
|
<View style={styles.avatarWrapper}>
|
||||||
{beneficiary.avatar ? (
|
{beneficiary.avatar ? (
|
||||||
@ -52,22 +92,41 @@ function BeneficiaryCard({ beneficiary, onPress }: BeneficiaryCardProps) {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Name */}
|
{/* Name and Status */}
|
||||||
<View style={styles.info}>
|
<View style={styles.info}>
|
||||||
<Text style={styles.name} numberOfLines={1}>{beneficiary.name}</Text>
|
<Text style={styles.name} numberOfLines={1}>{beneficiary.name}</Text>
|
||||||
|
{/* Equipment status badge */}
|
||||||
|
{isAwaitingEquipment && statusConfig && (
|
||||||
|
<View style={[styles.statusBadge, { backgroundColor: statusConfig.bgColor }]}>
|
||||||
|
<Ionicons name={statusConfig.icon} size={14} color={statusConfig.color} />
|
||||||
|
<Text style={[styles.statusText, { color: statusConfig.color }]}>
|
||||||
|
{statusConfig.label}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Warning icon if no subscription */}
|
{/* Warning icon if no subscription (only for active equipment) */}
|
||||||
{hasNoSubscription && (
|
{hasNoSubscription && (
|
||||||
<View style={styles.warningContainer}>
|
<View style={styles.warningContainer}>
|
||||||
<Ionicons name="warning" size={20} color={AppColors.warning} />
|
<Ionicons name="warning" size={20} color={AppColors.warning} />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Arrow */}
|
{/* Action button or Arrow */}
|
||||||
|
{equipmentStatus === 'delivered' ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.activateButton}
|
||||||
|
onPress={onActivate}
|
||||||
|
activeOpacity={0.8}
|
||||||
|
>
|
||||||
|
<Text style={styles.activateButtonText}>Activate</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : (
|
||||||
<View style={styles.arrowContainer}>
|
<View style={styles.arrowContainer}>
|
||||||
<Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
|
<Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
|
||||||
</View>
|
</View>
|
||||||
|
)}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -133,7 +192,20 @@ export default function HomeScreen() {
|
|||||||
|
|
||||||
const handleBeneficiaryPress = (beneficiary: Beneficiary) => {
|
const handleBeneficiaryPress = (beneficiary: Beneficiary) => {
|
||||||
setCurrentBeneficiary(beneficiary);
|
setCurrentBeneficiary(beneficiary);
|
||||||
|
// If equipment is not active yet, show status page instead of dashboard
|
||||||
|
if (beneficiary.equipmentStatus && ['ordered', 'shipped'].includes(beneficiary.equipmentStatus)) {
|
||||||
|
router.push(`/(tabs)/beneficiaries/${beneficiary.id}`);
|
||||||
|
} else {
|
||||||
router.push(`/(tabs)/beneficiaries/${beneficiary.id}/dashboard`);
|
router.push(`/(tabs)/beneficiaries/${beneficiary.id}/dashboard`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleActivate = (beneficiary: Beneficiary) => {
|
||||||
|
setCurrentBeneficiary(beneficiary);
|
||||||
|
router.push({
|
||||||
|
pathname: '/(auth)/activate',
|
||||||
|
params: { lovedOneName: beneficiary.name, beneficiaryId: beneficiary.id.toString() },
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDisplayName = () => {
|
const getDisplayName = () => {
|
||||||
@ -213,6 +285,7 @@ export default function HomeScreen() {
|
|||||||
<BeneficiaryCard
|
<BeneficiaryCard
|
||||||
beneficiary={item}
|
beneficiary={item}
|
||||||
onPress={() => handleBeneficiaryPress(item)}
|
onPress={() => handleBeneficiaryPress(item)}
|
||||||
|
onActivate={() => handleActivate(item)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
contentContainerStyle={styles.listContent}
|
contentContainerStyle={styles.listContent}
|
||||||
@ -399,6 +472,31 @@ const styles = StyleSheet.create({
|
|||||||
warningContainer: {
|
warningContainer: {
|
||||||
marginRight: Spacing.sm,
|
marginRight: Spacing.sm,
|
||||||
},
|
},
|
||||||
|
statusBadge: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingHorizontal: Spacing.sm,
|
||||||
|
paddingVertical: 4,
|
||||||
|
borderRadius: BorderRadius.md,
|
||||||
|
marginTop: 4,
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
gap: 4,
|
||||||
|
},
|
||||||
|
statusText: {
|
||||||
|
fontSize: FontSizes.xs,
|
||||||
|
fontWeight: FontWeights.medium,
|
||||||
|
},
|
||||||
|
activateButton: {
|
||||||
|
backgroundColor: AppColors.primary,
|
||||||
|
paddingHorizontal: Spacing.md,
|
||||||
|
paddingVertical: Spacing.sm,
|
||||||
|
borderRadius: BorderRadius.md,
|
||||||
|
},
|
||||||
|
activateButtonText: {
|
||||||
|
color: AppColors.white,
|
||||||
|
fontSize: FontSizes.sm,
|
||||||
|
fontWeight: FontWeights.semibold,
|
||||||
|
},
|
||||||
arrowContainer: {
|
arrowContainer: {
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user