Vou criar um aplicativo de bônus completo com funcionalidades essenciais. Aqui está uma estrutura completa:
## 📱 **App de Bônus – Sistema Completo**
### **1. Estrutura Principal**
“`javascript
// App.js
import React, { useState, useEffect } from ‘react’;
import { NavigationContainer } from ‘@react-navigation/native’;
import { createBottomTabNavigator } from ‘@react-navigation/bottom-tabs’;
import { Ionicons } from ‘@expo/vector-icons’;
// Telas
import HomeScreen from ‘./screens/HomeScreen’;
import BonusScreen from ‘./screens/BonusScreen’;
import MissionsScreen from ‘./screens/MissionsScreen’;
import ProfileScreen from ‘./screens/ProfileScreen’;
import StoreScreen from ‘./screens/StoreScreen’;
const Tab = createBottomTabNavigator();
export default function App() {
return (
tabBarIcon: ({ color, size }) => {
const icons = {
Home: ‘home’,
Bônus: ‘gift’,
Missões: ‘flag’,
Loja: ‘cart’,
Perfil: ‘person’,
};

return
},
})}
>
);
}
“`
### **2. Tela Principal (Home)**
“`javascript
// screens/HomeScreen.js
import React, { useState, useEffect } from ‘react’;
import {
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity,
Image,
Alert,
} from ‘react-native’;
export default function HomeScreen({ navigation }) {
const [userPoints, setUserPoints] = useState(1250);
const [dailyBonus, setDailyBonus] = useState(true);
const [streak, setStreak] = useState(5);
const bonuses = [
{ id: 1, title: ‘Bônus Diário’, points: 100, icon: ‘🎁’, claimed: false },
{ id: 2, title: ‘Primeira Compra’, points: 500, icon: ‘🛒’, claimed: true },
{ id: 3, title: ‘Indique Amigos’, points: 250, icon: ‘👥’, claimed: false },
{ id: 4, title: ‘Aniversário’, points: 1000, icon: ‘🎂’, claimed: false },
];
const claimBonus = (bonusId) => {
const bonus = bonuses.find(b => b.id === bonusId);
if (bonus && !bonus.claimed) {
setUserPoints(prev => prev + bonus.points);
Alert.alert(‘Sucesso!’, `Você ganhou ${bonus.points} pontos!`);
// Atualizar status do bônus no backend
}
};
return (
{/* Header com Pontos */}
{/* Streak Diário */}
{[…Array(7)].map((_, index) => (
))}
{/* Bônus Disponíveis */}
{bonuses.map(bonus => (
disabled={bonus.claimed}
>
{bonus.claimed ? ‘Resgatado’ : ‘Resgatar’}
))}
{/* Missões Rápidas */}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: ‘#f5f5f5’,
},
header: {
backgroundColor: ‘#6C63FF’,
padding: 20,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
},
welcomeText: {
color: ‘white’,
fontSize: 18,
marginBottom: 10,
},
pointsContainer: {
alignItems: ‘center’,
marginVertical: 20,
},
pointsLabel: {
color: ‘rgba(255,255,255,0.8)’,
fontSize: 12,
},
pointsValue: {
color: ‘white’,
fontSize: 48,
fontWeight: ‘bold’,
},
pointsCurrency: {
color: ‘rgba(255,255,255,0.8)’,
fontSize: 14,
},
streakContainer: {
backgroundColor: ‘white’,
margin: 15,
padding: 20,
borderRadius: 15,
elevation: 3,
},
sectionTitle: {
fontSize: 18,
fontWeight: ‘bold’,
marginBottom: 15,
},
streakDays: {
flexDirection: ‘row’,
justifyContent: ‘space-between’,
marginBottom: 20,
},
streakDay: {
alignItems: ‘center’,
padding: 10,
borderRadius: 10,
backgroundColor: ‘#f0f0f0’,
width: 40,
},
streakDayActive: {
backgroundColor: ‘#6C63FF’,
},
streakDayText: {
fontWeight: ‘bold’,
},
streakDayLabel: {
fontSize: 10,
marginTop: 5,
},
claimButton: {
backgroundColor: ‘#6C63FF’,
padding: 15,
borderRadius: 10,
alignItems: ‘center’,
},
claimButtonText: {
color: ‘white’,
fontWeight: ‘bold’,
fontSize: 16,
},
bonusesContainer: {
margin: 15,
},
bonusCard: {
flexDirection: ‘row’,
backgroundColor: ‘white’,

padding: 15,
borderRadius: 10,
alignItems: ‘center’,
marginBottom: 10,
elevation: 2,
},
bonusIcon: {
fontSize: 30,
marginRight: 15,
},
bonusInfo: {
flex: 1,
},
bonusTitle: {
fontSize: 16,
fontWeight: ‘bold’,
},
bonusPoints: {
color: ‘#6C63FF’,
fontWeight: ‘bold’,
},
bonusStatus: {
paddingHorizontal: 15,
paddingVertical: 8,
borderRadius: 20,
},
available: {
backgroundColor: ‘#4CAF50’,
},
claimed: {
backgroundColor: ‘#9E9E9E’,
},
bonusStatusText: {
color: ‘white’,
fontSize: 12,
},
missionsContainer: {
margin: 15,
marginBottom: 30,
},
quickMissions: {
flexDirection: ‘row’,
justifyContent: ‘space-between’,
},
missionButton: {
backgroundColor: ‘white’,
padding: 15,
borderRadius: 10,
alignItems: ‘center’,
flex: 1,
marginHorizontal: 5,
elevation: 2,
},
missionIcon: {
fontSize: 24,
marginBottom: 5,
},
missionText: {
fontSize: 12,
textAlign: ‘center’,
marginBottom: 5,
},
missionPoints: {
color: ‘#6C63FF’,
fontWeight: ‘bold’,
fontSize: 12,
},
});
“`
### **3. Sistema de Bônus (Backend Simulado)**
“`javascript
// services/BonusService.js
class BonusService {
constructor() {
this.userPoints = 1000;
this.bonuses = [
{
id: ‘daily’,
type: ‘daily’,
points: 100,
multiplier: 1,
cooldown: 24 * 60 * 60 * 1000, // 24 horas
lastClaimed: null
},
{
id: ‘referral’,
type: ‘referral’,
points: 500,
maxClaims: 10,
claimedCount: 0
},
{
id: ‘first_purchase’,
type: ‘one_time’,
points: 1000,
claimed: false
}
];
}
async claimDailyBonus(userId) {
const bonus = this.bonuses.find(b => b.type === ‘daily’);
const now = Date.now();
if (bonus.lastClaimed && (now – bonus.lastClaimed) < bonus.cooldown) { throw new Error('Bônus já resgatado hoje. Volte amanhã!'); } bonus.lastClaimed = now; this.userPoints += bonus.points * bonus.multiplier; return { success: true, points: bonus.points * bonus.multiplier, totalPoints: this.userPoints }; } async claimReferralBonus(userId, referralCode) { const bonus = this.bonuses.find(b => b.type === ‘referral’);
if (bonus.claimedCount >= bonus.maxClaims) {
throw new Error(‘Limite de indicações atingido’);
}
bonus.claimedCount++;
this.userPoints += bonus.points;
return {
success: true,
points: bonus.points,
totalPoints: this.userPoints,
remainingReferrals: bonus.maxClaims – bonus.claimedCount
};
}
async checkAchievements(userId) {
const achievements = [
{ id: ‘login_3_days’, points: 50, completed: false },
{ id: ‘first_purchase’, points: 200, completed: false },
{ id: ‘share_app’, points: 100, completed: false },
{ id: ‘complete_profile’, points: 150, completed: false }
];
return achievements;
}
}
export default new BonusService();
“`
### **4. Tela de Missões**
“`javascript
// screens/MissionsScreen.js
import React, { useState } from ‘react’;
import {
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity,
FlatList,
} from ‘react-native’;
const missionsData = [
{
id: ‘1’,
title: ‘Missão Diária’,
description: ‘Faça login por 3 dias consecutivos’,
reward: 150,
progress: 2,
total: 3,
type: ‘daily’,
icon: ‘🔥’,
},
{
id: ‘2’,
title: ‘Explorador’,
description: ‘Complete seu perfil 100%’,
reward: 200,
progress: 80,
total: 100,
type: ‘achievement’,
icon: ‘⭐’,
},
{
id: ‘3’,
title: ‘Social’,
description: ‘Indique 3 amigos’,
reward: 500,
progress: 1,
total: 3,
type: ‘social’,
icon: ‘👥’,
},
{
id: ‘4’,
title: ‘Comprador’,
description: ‘Faça sua primeira compra’,
reward: 1000,
progress: 0,
total: 1,
type: ‘purchase’,
icon: ‘🛒’,
},
];
export default function MissionsScreen() {
const [missions, setMissions] = useState(missionsData);
const claimMission = (missionId) => {
const mission = missions.find(m => m.id === missionId);
if (mission.progress >= mission.total) {
Alert.alert(‘Missão Concluída!’, `Você ganhou ${mission.reward} pontos!`);
// Atualizar no backend
}
};
const renderMission = ({ item }) => {
const progressPercentage = (item.progress / item.total) * 100;
return (
{item.progress}/{item.total}
]}
onPress={() => claimMission(item.id)}
disabled={item.progress < item.total}
>
{item.progress >= item.total ? ‘Resgatar’ : ‘Em andamento’}
);
};
return (
contentContainerStyle={styles.listContainer}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: ‘#f5f5f5’,
},
header: {
backgroundColor: ‘#6C63FF’,
padding: 20,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
},
headerTitle: {
color: ‘white’,
fontSize: 24,
fontWeight: ‘bold’,
},
headerSubtitle: {
color: ‘rgba(255,255,255,0.8)’,
fontSize: 14,
marginTop: 5,
},
listContainer: {
padding: 15,
},
missionCard: {
backgroundColor: ‘white’,
borderRadius: 15,
padding: 20,
marginBottom: 15,
elevation: 3,
},
missionHeader: {
flexDirection: ‘row’,
alignItems: ‘center’,
marginBottom: 15,
},
missionIcon: {
fontSize: 30,
marginRight: 15,
},
missionInfo: {
flex: 1,
},
missionTitle: {
fontSize: 16,
fontWeight: ‘bold’,
marginBottom: 5,
},
missionDescription: {
color: ‘#666’,
fontSize: 14,
},
rewardBadge: {
backgroundColor: ‘#FFD700’,
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 15,
},
rewardText: {
fontWeight: ‘bold’,
color: ‘#333’,
},
progressContainer: {
marginBottom: 15,
},
progressBar: {
height: 8,
backgroundColor: ‘#f0f0f0’,
borderRadius: 4,
overflow: ‘hidden’,
marginBottom: 5,

