diff --git a/mobile/assets/illustrations/index.tsx b/mobile/assets/illustrations/index.tsx
new file mode 100644
index 0000000..75a5b3e
--- /dev/null
+++ b/mobile/assets/illustrations/index.tsx
@@ -0,0 +1,112 @@
+import React from 'react';
+import Svg, { Circle, Line, Path, Rect } from 'react-native-svg';
+
+export type IllustrationAssetName =
+ | 'groups'
+ | 'transactions'
+ | 'notifications'
+ | 'search'
+ | 'wallet'
+ | 'error'
+ | 'success'
+ | 'default';
+
+export function GroupsIllustration() {
+ return (
+
+ );
+}
+
+export function TransactionsIllustration() {
+ return (
+
+ );
+}
+
+export function NotificationsIllustration() {
+ return (
+
+ );
+}
+
+export function SearchIllustration() {
+ return (
+
+ );
+}
+
+export function WalletIllustration() {
+ return (
+
+ );
+}
+
+export function ErrorIllustration() {
+ return (
+
+ );
+}
+
+export function SuccessIllustration() {
+ return (
+
+ );
+}
+
+export function DefaultIllustration() {
+ return (
+
+ );
+}
diff --git a/mobile/components/ui/EmptyState.tsx b/mobile/components/ui/EmptyState.tsx
index 40be38f..856d797 100644
--- a/mobile/components/ui/EmptyState.tsx
+++ b/mobile/components/ui/EmptyState.tsx
@@ -12,12 +12,14 @@ interface Props {
}
export function EmptyState({ icon, illustration, title, message, actionLabel, onAction }: Props) {
- // Support both icon prop and illustration type
- const displayIcon = icon || (illustration ? getIllustration(illustration).emoji : '📦');
+ const selected = illustration ? getIllustration(illustration) : getIllustration('default');
+ const useFallbackIcon = Boolean(icon);
return (
- {displayIcon}
+
+ {useFallbackIcon ? {icon} : selected.render()}
+
{title}
{message}
{actionLabel && (
@@ -31,7 +33,8 @@ export function EmptyState({ icon, illustration, title, message, actionLabel, on
const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24 },
- icon: { fontSize: 48, marginBottom: 12 },
+ illustration: { marginBottom: 14 },
+ icon: { fontSize: 48 },
title: { fontSize: 18, fontWeight: '600', color: '#F1F5F9', marginBottom: 8 },
message: { fontSize: 14, color: '#94A3B8', textAlign: 'center', marginBottom: 20 },
button: {
diff --git a/mobile/components/ui/Illustration.tsx b/mobile/components/ui/Illustration.tsx
index a149a74..6fdcaea 100644
--- a/mobile/components/ui/Illustration.tsx
+++ b/mobile/components/ui/Illustration.tsx
@@ -2,6 +2,18 @@
* Empty State Illustrations
* Visual assets for empty state components
*/
+import React from 'react';
+import type { ReactNode } from 'react';
+import {
+ DefaultIllustration,
+ ErrorIllustration,
+ GroupsIllustration,
+ NotificationsIllustration,
+ SearchIllustration,
+ SuccessIllustration,
+ TransactionsIllustration,
+ WalletIllustration,
+} from '../../assets/illustrations';
export type IllustrationType =
| 'groups'
@@ -14,43 +26,43 @@ export type IllustrationType =
| 'default';
interface IllustrationConfig {
- emoji: string;
description: string;
+ render: () => ReactNode;
}
// Map of illustration types to their visual representation
export const illustrations: Record = {
groups: {
- emoji: '👥',
description: 'No groups yet',
+ render: () => ,
},
transactions: {
- emoji: '💳',
description: 'No transactions yet',
+ render: () => ,
},
notifications: {
- emoji: '🔔',
description: 'No notifications',
+ render: () => ,
},
search: {
- emoji: '🔍',
description: 'No results found',
+ render: () => ,
},
wallet: {
- emoji: '💼',
description: 'No wallet connected',
+ render: () => ,
},
error: {
- emoji: '⚠️',
description: 'Something went wrong',
+ render: () => ,
},
success: {
- emoji: '✅',
description: 'Success',
+ render: () => ,
},
default: {
- emoji: '📦',
description: 'Nothing here',
+ render: () => ,
},
};
@@ -65,5 +77,15 @@ export function getIllustration(type: IllustrationType): IllustrationConfig {
* Get illustration emoji by type
*/
export function getIllustrationEmoji(type: IllustrationType): string {
- return getIllustration(type).emoji;
-}
\ No newline at end of file
+ const fallbackMap: Record = {
+ groups: '👥',
+ transactions: '💳',
+ notifications: '🔔',
+ search: '🔍',
+ wallet: '💼',
+ error: '⚠️',
+ success: '✅',
+ default: '📦',
+ };
+ return fallbackMap[type];
+}