346 lines
8.4 KiB
TypeScript
346 lines
8.4 KiB
TypeScript
import React, { useState, useEffect, useRef } from 'react';
|
||
import {
|
||
View,
|
||
Text,
|
||
TouchableOpacity,
|
||
StyleSheet,
|
||
SafeAreaView,
|
||
ScrollView,
|
||
Alert,
|
||
} from 'react-native';
|
||
import { useRouter } from 'expo-router';
|
||
import { Colors, Fonts } from '../src/constants/theme';
|
||
import {
|
||
Home,
|
||
FileText,
|
||
BarChart2,
|
||
Settings,
|
||
Star,
|
||
} from 'lucide-react-native';
|
||
|
||
const PURPLE = '#6a00fa';
|
||
const CARD_BG = '#fff';
|
||
|
||
export default function InicioScreen() {
|
||
const router = useRouter();
|
||
|
||
// --- authentication guard (placeholder) ---
|
||
useEffect(() => {
|
||
const isAuthenticated = true; // trocar por verificação real
|
||
if (!isAuthenticated) {
|
||
router.replace('/login' as any);
|
||
}
|
||
}, []);
|
||
|
||
// --- checklist state ---
|
||
const [tasks, setTasks] = useState([
|
||
{ id: 1, label: 'Estudar para intermédio', done: false },
|
||
{ id: 2, label: 'Ler artigo técnico', done: false },
|
||
{ id: 3, label: 'Fazer exercícios', done: false },
|
||
]);
|
||
const toggleTask = (id: number) => {
|
||
setTasks((prev) =>
|
||
prev.map((t) => (t.id === id ? { ...t, done: !t.done } : t))
|
||
);
|
||
};
|
||
|
||
// --- habits rating ---
|
||
const [rating, setRating] = useState(4);
|
||
|
||
// --- pomodoro timer ---
|
||
const [secondsLeft, setSecondsLeft] = useState(25 * 60);
|
||
const [running, setRunning] = useState(false);
|
||
const intervalRef = useRef<any>(null);
|
||
|
||
useEffect(() => {
|
||
if (running) {
|
||
intervalRef.current = setInterval(() => {
|
||
setSecondsLeft((s) => {
|
||
if (s <= 1) {
|
||
clearInterval(intervalRef.current);
|
||
setRunning(false);
|
||
return 0;
|
||
}
|
||
return s - 1;
|
||
});
|
||
}, 1000);
|
||
} else {
|
||
if (intervalRef.current) {
|
||
clearInterval(intervalRef.current);
|
||
}
|
||
}
|
||
return () => {
|
||
if (intervalRef.current) clearInterval(intervalRef.current);
|
||
};
|
||
}, [running]);
|
||
|
||
const startTimer = () => {
|
||
if (!running) {
|
||
setSecondsLeft(25 * 60);
|
||
setRunning(true);
|
||
}
|
||
};
|
||
|
||
const formatTime = (sec: number) => {
|
||
const m = Math.floor(sec / 60)
|
||
.toString()
|
||
.padStart(2, '0');
|
||
const s = (sec % 60).toString().padStart(2, '0');
|
||
return `${m}:${s}`;
|
||
};
|
||
|
||
return (
|
||
<SafeAreaView style={styles.safe}>
|
||
<ScrollView contentContainerStyle={styles.scroll}>
|
||
{/* header */}
|
||
<View style={styles.header}>
|
||
<View>
|
||
<Text style={styles.greeting}>Hoje é um bom dia</Text>
|
||
<Text style={styles.subtitle}>
|
||
Olá, Matheus! Preparado para o seu dia de produtividade?
|
||
</Text>
|
||
</View>
|
||
<Text style={styles.waveEmoji}>👋</Text>
|
||
</View>
|
||
|
||
{/* desafios do dia card */}
|
||
<View style={styles.card}>
|
||
<Text style={styles.cardTitle}>Desafios do Dia</Text>
|
||
{tasks.map((t) => (
|
||
<TouchableOpacity
|
||
key={t.id}
|
||
style={styles.checkItem}
|
||
onPress={() => toggleTask(t.id)}
|
||
>
|
||
<Text style={[styles.checkBox, t.done && styles.done]}>✓</Text>
|
||
<Text
|
||
style={[
|
||
styles.checkLabel,
|
||
t.done && styles.checkLabelDone,
|
||
]}
|
||
>
|
||
{t.label}
|
||
</Text>
|
||
</TouchableOpacity>
|
||
))}
|
||
<TouchableOpacity
|
||
style={styles.addButton}
|
||
onPress={() => Alert.alert('Adicionar','implementação futura')}
|
||
>
|
||
<Text style={styles.addButtonText}>+ Adicionar desafios diários</Text>
|
||
</TouchableOpacity>
|
||
</View>
|
||
|
||
{/* hábitos card */}
|
||
<View style={styles.card}>
|
||
<Text style={styles.cardTitle}>Hábitos</Text>
|
||
<View style={styles.ratingRow}>
|
||
{Array.from({ length: 5 }).map((_, i) => (
|
||
<Star
|
||
key={i}
|
||
size={20}
|
||
color={i < rating ? '#f5c518' : '#ccc'}
|
||
onPress={() => setRating(i + 1)}
|
||
/>
|
||
))}
|
||
</View>
|
||
<View style={styles.habitsRow}>
|
||
<TouchableOpacity style={[styles.habitButton, { backgroundColor: '#A0E9FD' }]}
|
||
activeOpacity={0.7}
|
||
>
|
||
<Text>📘</Text>
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={[styles.habitButton, { backgroundColor: '#B2F59C' }]}
|
||
activeOpacity={0.7}
|
||
>
|
||
<Text>🧘</Text>
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={[styles.habitButton, { backgroundColor: '#FFD59C' }]}
|
||
activeOpacity={0.7}
|
||
>
|
||
<Text>🏋️♂️</Text>
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={[styles.habitButton, styles.habitAdd]}
|
||
activeOpacity={0.7}
|
||
>
|
||
<Text>+</Text>
|
||
</TouchableOpacity>
|
||
</View>
|
||
</View>
|
||
|
||
{/* modo foco card */}
|
||
<View style={styles.card}>
|
||
<Text style={styles.cardTitle}>Modo Foco</Text>
|
||
<View style={styles.focusRow}>
|
||
<TouchableOpacity
|
||
style={styles.timerBlock}
|
||
onPress={startTimer}
|
||
>
|
||
<Text style={styles.timerText}>{formatTime(secondsLeft)}</Text>
|
||
</TouchableOpacity>
|
||
<Text style={styles.focusText}>
|
||
Produtividade é o segredo do sucesso
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
</ScrollView>
|
||
|
||
{/* bottom navigation */}
|
||
<View style={styles.bottomNav}>
|
||
<TouchableOpacity style={styles.navItem} disabled>
|
||
<Home size={24} color={PURPLE} />
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={styles.navItem}>
|
||
<FileText size={24} color="#666" />
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={styles.navItem}>
|
||
<BarChart2 size={24} color="#666" />
|
||
</TouchableOpacity>
|
||
<TouchableOpacity style={styles.navItem}>
|
||
<Settings size={24} color="#666" />
|
||
</TouchableOpacity>
|
||
</View>
|
||
</SafeAreaView>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
safe: {
|
||
flex: 1,
|
||
backgroundColor: PURPLE,
|
||
},
|
||
scroll: {
|
||
padding: 20,
|
||
paddingBottom: 80,
|
||
},
|
||
header: {
|
||
flexDirection: 'row',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
marginBottom: 20,
|
||
},
|
||
greeting: {
|
||
fontSize: 24,
|
||
fontWeight: 'bold',
|
||
color: '#fff',
|
||
},
|
||
subtitle: {
|
||
fontSize: 14,
|
||
color: '#eee',
|
||
marginTop: 4,
|
||
},
|
||
waveEmoji: {
|
||
fontSize: 28,
|
||
},
|
||
card: {
|
||
backgroundColor: CARD_BG,
|
||
borderRadius: 24,
|
||
padding: 16,
|
||
marginBottom: 20,
|
||
},
|
||
cardTitle: {
|
||
fontSize: 18,
|
||
fontWeight: '600',
|
||
marginBottom: 12,
|
||
},
|
||
checkItem: {
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
marginBottom: 8,
|
||
},
|
||
checkBox: {
|
||
width: 24,
|
||
height: 24,
|
||
borderWidth: 1,
|
||
borderColor: '#666',
|
||
marginRight: 8,
|
||
textAlign: 'center',
|
||
lineHeight: 24,
|
||
},
|
||
done: {
|
||
backgroundColor: '#6a0fa0',
|
||
color: '#fff',
|
||
borderColor: '#6a0fa0',
|
||
},
|
||
checkLabel: {
|
||
fontSize: 16,
|
||
color: '#333',
|
||
},
|
||
checkLabelDone: {
|
||
textDecorationLine: 'line-through',
|
||
color: '#999',
|
||
},
|
||
addButton: {
|
||
marginTop: 12,
|
||
backgroundColor: PURPLE,
|
||
padding: 12,
|
||
borderRadius: 8,
|
||
alignItems: 'center',
|
||
},
|
||
addButtonText: {
|
||
color: '#fff',
|
||
fontWeight: '600',
|
||
},
|
||
ratingRow: {
|
||
flexDirection: 'row',
|
||
marginBottom: 12,
|
||
},
|
||
habitsRow: {
|
||
flexDirection: 'row',
|
||
justifyContent: 'space-between',
|
||
},
|
||
habitButton: {
|
||
width: 50,
|
||
height: 50,
|
||
borderRadius: 8,
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
},
|
||
habitAdd: {
|
||
borderWidth: 1,
|
||
borderStyle: 'dashed',
|
||
borderColor: '#666',
|
||
backgroundColor: 'transparent',
|
||
},
|
||
focusRow: {
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
},
|
||
timerBlock: {
|
||
width: 80,
|
||
height: 80,
|
||
backgroundColor: '#3b44f6',
|
||
borderRadius: 12,
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
marginRight: 12,
|
||
},
|
||
timerText: {
|
||
color: '#fff',
|
||
fontSize: 20,
|
||
fontWeight: 'bold',
|
||
},
|
||
focusText: {
|
||
flex: 1,
|
||
fontSize: 14,
|
||
color: '#333',
|
||
},
|
||
bottomNav: {
|
||
position: 'absolute',
|
||
bottom: 0,
|
||
left: 0,
|
||
right: 0,
|
||
height: 60,
|
||
flexDirection: 'row',
|
||
justifyContent: 'space-around',
|
||
alignItems: 'center',
|
||
backgroundColor: CARD_BG,
|
||
borderTopWidth: 1,
|
||
borderColor: '#ddd',
|
||
},
|
||
navItem: {
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
},
|
||
});
|