feat: 更新心情记录功能和界面
- 调整启动画面中的图片宽度,提升视觉效果 - 移除引导页面相关组件,简化应用结构 - 新增心情统计页面,支持用户查看和分析心情数据 - 优化心情卡片组件,增强用户交互体验 - 更新登录页面标题,提升品牌一致性 - 新增心情日历和编辑功能,支持用户记录和管理心情
This commit is contained in:
@@ -1,76 +1,111 @@
|
||||
import { MoodCheckin, getMoodConfig } from '@/services/moodCheckins';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { ThemedText } from './ThemedText';
|
||||
import { ThemedView } from './ThemedView';
|
||||
|
||||
interface MoodCardProps {
|
||||
moodCheckin: MoodCheckin | null;
|
||||
onPress: () => void;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function MoodCard({ onPress }: MoodCardProps) {
|
||||
export function MoodCard({ moodCheckin, onPress, isLoading = false }: MoodCardProps) {
|
||||
const moodConfig = moodCheckin ? getMoodConfig(moodCheckin.moodType) : null;
|
||||
|
||||
return (
|
||||
<ThemedView style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<ThemedText style={styles.title}>心情</ThemedText>
|
||||
<ThemedText style={styles.subtitle}>记录你的每日心情</ThemedText>
|
||||
<TouchableOpacity onPress={onPress} style={styles.moodCardContent} disabled={isLoading}>
|
||||
<View style={styles.cardHeaderRow}>
|
||||
<View style={styles.moodIconContainer}>
|
||||
{moodCheckin ? (
|
||||
<Text style={styles.moodIcon}>
|
||||
{moodConfig?.emoji || '😊'}
|
||||
</Text>
|
||||
) : (
|
||||
<Text style={styles.moodIcon}>😊</Text>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.cardTitle}>心情</Text>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity style={styles.content} onPress={onPress}>
|
||||
<View style={styles.moodIcon}>
|
||||
<Text style={styles.emoji}>😊</Text>
|
||||
<Text style={styles.moodSubtitle}>记录你的每日心情</Text>
|
||||
|
||||
{isLoading ? (
|
||||
<View style={styles.moodPreview}>
|
||||
<Text style={styles.moodLoadingText}>加载中...</Text>
|
||||
</View>
|
||||
<ThemedText style={styles.moodText}>点击记录今日心情</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</ThemedView>
|
||||
) : moodCheckin ? (
|
||||
<View style={styles.moodPreview}>
|
||||
<Text style={styles.moodPreviewText}>
|
||||
{moodConfig?.label || moodCheckin.moodType}
|
||||
</Text>
|
||||
<Text style={styles.moodPreviewTime}>
|
||||
{dayjs(moodCheckin.createdAt).format('HH:mm')}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={styles.moodEmptyText}>点击记录心情</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
marginBottom: 16,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
moodCardContent: {
|
||||
width: '100%',
|
||||
},
|
||||
header: {
|
||||
marginBottom: 12,
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
marginBottom: 4,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 14,
|
||||
opacity: 0.6,
|
||||
},
|
||||
content: {
|
||||
cardHeaderRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 8,
|
||||
marginBottom: 12,
|
||||
},
|
||||
moodIconContainer: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 8,
|
||||
backgroundColor: '#DCFCE7',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 10,
|
||||
},
|
||||
moodIcon: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: '#f0f0f0',
|
||||
justifyContent: 'center',
|
||||
fontSize: 14,
|
||||
},
|
||||
cardTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '800',
|
||||
color: '#192126',
|
||||
},
|
||||
moodSubtitle: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
marginTop: 4,
|
||||
marginBottom: 8,
|
||||
},
|
||||
moodPreview: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
marginTop: 4,
|
||||
},
|
||||
emoji: {
|
||||
fontSize: 20,
|
||||
moodPreviewText: {
|
||||
fontSize: 14,
|
||||
color: '#059669',
|
||||
fontWeight: '600',
|
||||
},
|
||||
moodText: {
|
||||
fontSize: 16,
|
||||
flex: 1,
|
||||
moodPreviewTime: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
},
|
||||
moodEmptyText: {
|
||||
fontSize: 12,
|
||||
color: '#9CA3AF',
|
||||
fontStyle: 'italic',
|
||||
marginTop: 4,
|
||||
},
|
||||
moodLoadingText: {
|
||||
fontSize: 12,
|
||||
color: '#9CA3AF',
|
||||
fontStyle: 'italic',
|
||||
marginTop: 4,
|
||||
},
|
||||
});
|
||||
199
components/MoodHistoryCard.tsx
Normal file
199
components/MoodHistoryCard.tsx
Normal file
@@ -0,0 +1,199 @@
|
||||
import { MoodCheckin, getMoodConfig } from '@/services/moodCheckins';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
interface MoodHistoryCardProps {
|
||||
moodCheckins: MoodCheckin[];
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export function MoodHistoryCard({ moodCheckins, title = '心情记录' }: MoodHistoryCardProps) {
|
||||
// 计算心情统计
|
||||
const moodStats = React.useMemo(() => {
|
||||
const stats = {
|
||||
total: moodCheckins.length,
|
||||
averageIntensity: 0,
|
||||
moodDistribution: {} as Record<string, number>,
|
||||
mostFrequentMood: '',
|
||||
};
|
||||
|
||||
if (moodCheckins.length === 0) return stats;
|
||||
|
||||
// 计算平均强度
|
||||
const totalIntensity = moodCheckins.reduce((sum, checkin) => sum + checkin.intensity, 0);
|
||||
stats.averageIntensity = Math.round(totalIntensity / moodCheckins.length);
|
||||
|
||||
// 计算心情分布
|
||||
moodCheckins.forEach(checkin => {
|
||||
const moodLabel = getMoodConfig(checkin.moodType)?.label || checkin.moodType;
|
||||
stats.moodDistribution[moodLabel] = (stats.moodDistribution[moodLabel] || 0) + 1;
|
||||
});
|
||||
|
||||
// 找出最频繁的心情
|
||||
const sortedMoods = Object.entries(stats.moodDistribution)
|
||||
.sort(([, a], [, b]) => b - a);
|
||||
stats.mostFrequentMood = sortedMoods[0]?.[0] || '';
|
||||
|
||||
return stats;
|
||||
}, [moodCheckins]);
|
||||
|
||||
// 获取最近的心情记录
|
||||
const recentMoods = moodCheckins
|
||||
.sort((a, b) => dayjs(b.createdAt).valueOf() - dayjs(a.createdAt).valueOf())
|
||||
.slice(0, 5);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
|
||||
{moodCheckins.length === 0 ? (
|
||||
<View style={styles.emptyState}>
|
||||
<Text style={styles.emptyText}>暂无心情记录</Text>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
{/* 统计信息 */}
|
||||
<View style={styles.statsContainer}>
|
||||
<View style={styles.statItem}>
|
||||
<Text style={styles.statValue}>{moodStats.total}</Text>
|
||||
<Text style={styles.statLabel}>总记录</Text>
|
||||
</View>
|
||||
<View style={styles.statItem}>
|
||||
<Text style={styles.statValue}>{moodStats.averageIntensity}</Text>
|
||||
<Text style={styles.statLabel}>平均强度</Text>
|
||||
</View>
|
||||
<View style={styles.statItem}>
|
||||
<Text style={styles.statValue}>{moodStats.mostFrequentMood}</Text>
|
||||
<Text style={styles.statLabel}>最常见</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 最近记录 */}
|
||||
<View style={styles.recentContainer}>
|
||||
<Text style={styles.sectionTitle}>最近记录</Text>
|
||||
{recentMoods.map((checkin, index) => {
|
||||
const moodConfig = getMoodConfig(checkin.moodType);
|
||||
return (
|
||||
<View key={checkin.id} style={styles.moodItem}>
|
||||
<View style={styles.moodInfo}>
|
||||
<Text style={styles.moodEmoji}>{moodConfig?.emoji}</Text>
|
||||
<View style={styles.moodDetails}>
|
||||
<Text style={styles.moodLabel}>{moodConfig?.label}</Text>
|
||||
<Text style={styles.moodDate}>
|
||||
{dayjs(checkin.createdAt).format('MM月DD日 HH:mm')}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.moodIntensity}>
|
||||
<Text style={styles.intensityText}>强度 {checkin.intensity}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
marginBottom: 16,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#192126',
|
||||
marginBottom: 16,
|
||||
},
|
||||
emptyState: {
|
||||
alignItems: 'center',
|
||||
paddingVertical: 32,
|
||||
},
|
||||
emptyText: {
|
||||
fontSize: 14,
|
||||
color: '#9CA3AF',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
statsContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginBottom: 20,
|
||||
paddingVertical: 16,
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 12,
|
||||
},
|
||||
statItem: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
statValue: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: '#192126',
|
||||
marginBottom: 4,
|
||||
},
|
||||
statLabel: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
},
|
||||
recentContainer: {
|
||||
marginTop: 8,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: '#192126',
|
||||
marginBottom: 12,
|
||||
},
|
||||
moodItem: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 8,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#F3F4F6',
|
||||
},
|
||||
moodInfo: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
moodEmoji: {
|
||||
fontSize: 20,
|
||||
marginRight: 12,
|
||||
},
|
||||
moodDetails: {
|
||||
flex: 1,
|
||||
},
|
||||
moodLabel: {
|
||||
fontSize: 14,
|
||||
fontWeight: '500',
|
||||
color: '#192126',
|
||||
marginBottom: 2,
|
||||
},
|
||||
moodDate: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
},
|
||||
moodIntensity: {
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
intensityText: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
fontWeight: '500',
|
||||
},
|
||||
});
|
||||
@@ -1,422 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Dimensions,
|
||||
Modal,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
const { width, height } = Dimensions.get('window');
|
||||
|
||||
interface MoodModalProps {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
onSave: (mood: string, date: string) => void;
|
||||
}
|
||||
|
||||
// 心情日历数据
|
||||
const generateCalendarData = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = today.getMonth();
|
||||
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||
const firstDayOfWeek = new Date(year, month, 1).getDay();
|
||||
|
||||
const calendar = [];
|
||||
const weeks = [];
|
||||
|
||||
// 添加空白日期
|
||||
for (let i = 0; i < firstDayOfWeek; i++) {
|
||||
weeks.push(null);
|
||||
}
|
||||
|
||||
// 添加实际日期
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
weeks.push(day);
|
||||
}
|
||||
|
||||
// 按周分组
|
||||
for (let i = 0; i < weeks.length; i += 7) {
|
||||
calendar.push(weeks.slice(i, i + 7));
|
||||
}
|
||||
|
||||
return { calendar, today: today.getDate(), month: month + 1, year };
|
||||
};
|
||||
|
||||
const moodOptions = [
|
||||
{ emoji: '😊', label: '开心', color: '#4CAF50' },
|
||||
{ emoji: '😢', label: '难过', color: '#2196F3' },
|
||||
{ emoji: '😰', label: '焦虑', color: '#FF9800' },
|
||||
{ emoji: '😴', label: '疲惫', color: '#9C27B0' },
|
||||
{ emoji: '😡', label: '愤怒', color: '#F44336' },
|
||||
{ emoji: '😐', label: '平静', color: '#607D8B' },
|
||||
];
|
||||
|
||||
export function MoodModal({ visible, onClose, onSave }: MoodModalProps) {
|
||||
const [selectedMood, setSelectedMood] = useState<string>('');
|
||||
const { calendar, today, month, year } = generateCalendarData();
|
||||
|
||||
const weekDays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||
const monthNames = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
|
||||
|
||||
const handleSave = () => {
|
||||
if (selectedMood) {
|
||||
const now = new Date();
|
||||
const timeString = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;
|
||||
onSave(selectedMood, timeString);
|
||||
onClose();
|
||||
setSelectedMood('');
|
||||
}
|
||||
};
|
||||
|
||||
const renderMoodIcon = (day: number | null, isToday: boolean) => {
|
||||
if (!day) return null;
|
||||
|
||||
if (isToday && selectedMood) {
|
||||
const mood = moodOptions.find(m => m.label === selectedMood);
|
||||
return (
|
||||
<View style={[styles.moodIconContainer, { backgroundColor: mood?.color }]}>
|
||||
<View style={styles.bearIcon}>
|
||||
<Text style={styles.bearEmoji}>🐻</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.defaultMoodIcon}>
|
||||
<Text style={styles.defaultMoodEmoji}>😊</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
animationType="slide"
|
||||
presentationStyle="pageSheet"
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={onClose}>
|
||||
<Text style={styles.backButton}>←</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>{year}年{monthNames[month - 1]}</Text>
|
||||
<TouchableOpacity>
|
||||
<Text style={styles.nextButton}>→</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView style={styles.content}>
|
||||
{/* 日历视图 */}
|
||||
<View style={styles.calendar}>
|
||||
<View style={styles.weekHeader}>
|
||||
{weekDays.map((day, index) => (
|
||||
<Text key={index} style={styles.weekDay}>{day}</Text>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{calendar.map((week, weekIndex) => (
|
||||
<View key={weekIndex} style={styles.weekRow}>
|
||||
{week.map((day, dayIndex) => (
|
||||
<View key={dayIndex} style={styles.dayContainer}>
|
||||
{day && (
|
||||
<>
|
||||
<Text style={[
|
||||
styles.dayNumber,
|
||||
day === today && styles.todayNumber
|
||||
]}>
|
||||
{day.toString().padStart(2, '0')}
|
||||
</Text>
|
||||
{renderMoodIcon(day, day === today)}
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 心情选择 */}
|
||||
<View style={styles.moodSection}>
|
||||
<Text style={styles.sectionTitle}>选择今日心情</Text>
|
||||
<View style={styles.moodOptions}>
|
||||
{moodOptions.map((mood, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[
|
||||
styles.moodOption,
|
||||
selectedMood === mood.label && styles.selectedMoodOption
|
||||
]}
|
||||
onPress={() => setSelectedMood(mood.label)}
|
||||
>
|
||||
<Text style={styles.moodEmoji}>{mood.emoji}</Text>
|
||||
<Text style={styles.moodLabel}>{mood.label}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 近期记录 */}
|
||||
<View style={styles.recentSection}>
|
||||
<Text style={styles.sectionTitle}>近期记录</Text>
|
||||
<Text style={styles.recentDate}>{year}年{month}月{today}日</Text>
|
||||
|
||||
{selectedMood && (
|
||||
<View style={styles.recentRecord}>
|
||||
<View style={styles.recordIcon}>
|
||||
<View style={styles.bearIcon}>
|
||||
<Text style={styles.bearEmoji}>🐻</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.recordMood}>{selectedMood}</Text>
|
||||
<View style={styles.spacer} />
|
||||
<Text style={styles.recordTime}>
|
||||
{new Date().getHours()}:{new Date().getMinutes().toString().padStart(2, '0')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* 保存按钮 */}
|
||||
<View style={styles.footer}>
|
||||
<TouchableOpacity
|
||||
style={[styles.saveButton, !selectedMood && styles.disabledButton]}
|
||||
onPress={handleSave}
|
||||
disabled={!selectedMood}
|
||||
>
|
||||
<Text style={styles.saveButtonText}>保存心情</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* 添加按钮 */}
|
||||
<TouchableOpacity style={styles.addButton} onPress={handleSave}>
|
||||
<Text style={styles.addButtonText}>+</Text>
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 16,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
backButton: {
|
||||
fontSize: 24,
|
||||
color: '#666',
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
},
|
||||
nextButton: {
|
||||
fontSize: 24,
|
||||
color: '#666',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
},
|
||||
calendar: {
|
||||
backgroundColor: '#fff',
|
||||
margin: 16,
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
},
|
||||
weekHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginBottom: 16,
|
||||
},
|
||||
weekDay: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
width: (width - 64) / 7,
|
||||
},
|
||||
weekRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginBottom: 16,
|
||||
},
|
||||
dayContainer: {
|
||||
width: (width - 64) / 7,
|
||||
alignItems: 'center',
|
||||
},
|
||||
dayNumber: {
|
||||
fontSize: 14,
|
||||
color: '#999',
|
||||
marginBottom: 8,
|
||||
},
|
||||
todayNumber: {
|
||||
color: '#333',
|
||||
fontWeight: '600',
|
||||
},
|
||||
moodIconContainer: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
bearIcon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 12,
|
||||
backgroundColor: 'rgba(255,255,255,0.9)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
bearEmoji: {
|
||||
fontSize: 12,
|
||||
},
|
||||
defaultMoodIcon: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
borderColor: '#ddd',
|
||||
borderStyle: 'dashed',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
defaultMoodEmoji: {
|
||||
fontSize: 16,
|
||||
opacity: 0.3,
|
||||
},
|
||||
moodSection: {
|
||||
backgroundColor: '#fff',
|
||||
margin: 16,
|
||||
marginTop: 0,
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
marginBottom: 16,
|
||||
},
|
||||
moodOptions: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
moodOption: {
|
||||
width: (width - 80) / 3,
|
||||
alignItems: 'center',
|
||||
paddingVertical: 16,
|
||||
marginBottom: 16,
|
||||
borderRadius: 12,
|
||||
backgroundColor: '#f8f8f8',
|
||||
},
|
||||
selectedMoodOption: {
|
||||
backgroundColor: '#e8f5e8',
|
||||
borderWidth: 2,
|
||||
borderColor: '#4CAF50',
|
||||
},
|
||||
moodEmoji: {
|
||||
fontSize: 24,
|
||||
marginBottom: 8,
|
||||
},
|
||||
moodLabel: {
|
||||
fontSize: 14,
|
||||
color: '#333',
|
||||
},
|
||||
recentSection: {
|
||||
backgroundColor: '#fff',
|
||||
margin: 16,
|
||||
marginTop: 0,
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
},
|
||||
recentDate: {
|
||||
fontSize: 14,
|
||||
color: '#999',
|
||||
marginBottom: 16,
|
||||
},
|
||||
recentRecord: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 12,
|
||||
},
|
||||
recordIcon: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
backgroundColor: '#4CAF50',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
recordMood: {
|
||||
fontSize: 16,
|
||||
color: '#333',
|
||||
fontWeight: '500',
|
||||
},
|
||||
spacer: {
|
||||
flex: 1,
|
||||
},
|
||||
recordTime: {
|
||||
fontSize: 14,
|
||||
color: '#999',
|
||||
},
|
||||
footer: {
|
||||
padding: 16,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
saveButton: {
|
||||
backgroundColor: '#4CAF50',
|
||||
borderRadius: 12,
|
||||
paddingVertical: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
disabledButton: {
|
||||
backgroundColor: '#ccc',
|
||||
},
|
||||
saveButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
addButton: {
|
||||
position: 'absolute',
|
||||
bottom: 100,
|
||||
right: 20,
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 28,
|
||||
backgroundColor: '#00C853',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
addButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 24,
|
||||
fontWeight: '300',
|
||||
},
|
||||
});
|
||||
@@ -40,8 +40,8 @@ export default function PrivacyConsentModal({
|
||||
>
|
||||
<View style={styles.overlay}>
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>欢迎来到普拉提助手</Text>
|
||||
|
||||
<Text style={styles.title}>欢迎来到Sealife</Text>
|
||||
|
||||
<View style={styles.contentContainer}>
|
||||
<Text style={styles.description}>
|
||||
点击"同意并继续"代表您已阅读并理解
|
||||
@@ -69,11 +69,11 @@ export default function PrivacyConsentModal({
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<TouchableOpacity style={styles.agreeButton} onPress={onAgree}>
|
||||
<Text style={styles.agreeButtonText}>同意并继续</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
|
||||
<TouchableOpacity style={styles.disagreeButton} onPress={onDisagree}>
|
||||
<Text style={styles.disagreeButtonText}>不同意并退出</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
Reference in New Issue
Block a user