Frontend Overview¶
The Certana Frontend is a cross-platform mobile application built with React Native and Expo, providing:
- Image upload and asset management
- Real-time verification interface
- History tracking with detailed results
- QR code generation for asset sharing
- Organization and API key management
- Dark mode support
Key Features¶
📱 Multi-Platform Support¶
- iOS - Native iOS app via Expo
- Android - Native Android app via Expo
- Web - Web version via React Native Web
🖼️ Image Management¶
- Upload images directly from device
- Browse and organize uploaded assets
- Tag and categorize assets
- Batch operations
✅ Verification¶
- Real-time verification interface
- Detailed results with confidence scores
- Watermark detection visualization
- Tamper detection maps
- Blockchain verification status
📊 History & Analytics¶
- Verification history tracking
- Detailed result breakdowns
- Verification statistics
- Filter and search
🔑 API Integration¶
- API key management
- Usage tracking and quota display
- Rate limit monitoring
Technology Stack¶
Frontend (React Native/Expo)
├── State Management: Async Storage
├── Navigation: React Navigation (Bottom Tabs + Drawer)
├── UI Components: React Native Paper
├── HTTP Client: Axios
├── Code Generation: jsbarcode, qrcode
└── Image Processing: expo-image-manipulator
Project Structure¶
frontend/
├── src/
│ ├── api/ # API services
│ │ ├── client.ts # Axios configuration
│ │ ├── authService.ts # Authentication
│ │ ├── assetService.ts # Asset management
│ │ ├── verificationService.ts
│ │ ├── blockchainService.ts
│ │ └── ...
│ │
│ ├── screens/ # Screen components
│ │ ├── HomeScreen.tsx
│ │ ├── UploadScreen.tsx
│ │ ├── VerifyScreen.tsx
│ │ ├── HistoryScreen.tsx
│ │ ├── LoginScreen.tsx
│ │ ├── SettingsScreen.tsx
│ │ └── ...
│ │
│ ├── components/ # Reusable components
│ │ ├── ImageCard.tsx
│ │ ├── VerificationResult.tsx
│ │ ├── LoadingSpinner.tsx
│ │ ├── ErrorBoundary.tsx
│ │ └── ...
│ │
│ ├── navigation/ # Navigation setup
│ │ ├── RootNavigator.tsx
│ │ ├── AuthNavigator.tsx
│ │ └── AppNavigator.tsx
│ │
│ ├── contexts/ # React Context
│ │ ├── AuthContext.tsx # Auth state
│ │ ├── ThemeContext.tsx # Theme state
│ │ └── ApiContext.tsx # API config
│ │
│ ├── types/ # TypeScript types
│ ├── utils/ # Utility functions
│ ├── constants/ # App constants
│ ├── App.tsx # Root component
│ └── index.ts # Entry point
│
├── android/ # Android native code
├── ios/ # iOS native code
├── babel.config.js
├── tsconfig.json
├── package.json
└── app.json
Key Screens¶
Authentication¶
- LoginScreen - Email/password login
- RegisterScreen - New user registration
- ForgotPasswordScreen - Password recovery
- OAuthScreen - Social login
Main App¶
- HomeScreen - Dashboard with recent assets
- UploadScreen - Image selection and upload
- VerifyScreen - Image verification interface
- HistoryScreen - Verification history
- DetailsScreen - Asset/verification details
- SettingsScreen - App configuration
Navigation Flow¶
RootNavigator
├── (Not Authenticated)
│ └── AuthNavigator
│ ├── LoginScreen
│ ├── RegisterScreen
│ └── ForgotPasswordScreen
│
└── (Authenticated)
├── AppNavigator (Bottom Tabs)
│ ├── HomeStack
│ │ ├── HomeScreen
│ │ └── DetailsScreen
│ │
│ ├── UploadStack
│ │ ├── UploadScreen
│ │ └── PreviewScreen
│ │
│ ├── VerifyStack
│ │ ├── VerifyScreen
│ │ └── ResultScreen
│ │
│ └── MoreStack (Drawer)
│ ├── HistoryScreen
│ ├── SettingsScreen
│ ├── OrganizationScreen
│ └── ApiKeysScreen
API Integration¶
Client Setup¶
// src/api/client.ts
const client = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Add auth token
client.interceptors.request.use((config) => {
const token = getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
Service Layer¶
// src/api/assetService.ts
export const assetService = {
uploadAsset(formData: FormData): Promise<Asset> { ... },
getAssets(page: number): Promise<Asset[]> { ... },
getAssetDetails(id: string): Promise<Asset> { ... },
searchAssets(query: string): Promise<Asset[]> { ... },
};
State Management¶
AuthContext¶
interface AuthContextType {
user: User | null;
token: string | null;
isLoading: boolean;
error: string | null;
login(email: string, password: string): Promise<void>;
register(data: RegisterData): Promise<void>;
logout(): Promise<void>;
refreshToken(): Promise<void>;
}
Theme Context¶
interface ThemeContextType {
isDark: boolean;
theme: MD3Theme;
toggleTheme(): void;
}
Main Dependencies¶
| Package | Version | Purpose |
|---|---|---|
| react-native | 0.81.5 | Core framework |
| expo | ~54.0.20 | Build & runtime |
| react-navigation | ^7.x | Navigation |
| react-native-paper | ^5.14.5 | UI components |
| axios | ^1.12.2 | HTTP client |
| @react-native-async-storage/async-storage | ^2.2.0 | Local storage |
| expo-image-picker | ^17.0.8 | Image selection |
| qrcode | ^1.5.4 | QR generation |
| typescript | ~5.9.3 | Type safety |
Performance Optimization¶
Image Caching¶
// Cache images after download
const cachedImage = await useImageCache(imageUrl);
Lazy Loading¶
// Lazy load screens for faster startup
const HistoryScreen = lazy(() => import('./HistoryScreen'));
Memoization¶
const ImageCard = memo(({ image }) => (
// Component definition
));