init
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, Animated } from 'react-native';
|
||||
import Button from '../Button';
|
||||
import { colors, fonts, spacing, borderRadius } from '../../utils/theme';
|
||||
import { getResultMessage, getStatLabel } from '../../services/gameService';
|
||||
|
||||
export default function GameResult({ gameType, score, details, onSave, onRetry, saving }) {
|
||||
const fadeIn = useRef(new Animated.Value(0)).current;
|
||||
const scaleScore = useRef(new Animated.Value(0)).current;
|
||||
|
||||
useEffect(() => {
|
||||
Animated.sequence([
|
||||
Animated.timing(fadeIn, { toValue: 1, duration: 400, useNativeDriver: true }),
|
||||
Animated.spring(scaleScore, { toValue: 1, useNativeDriver: true, speed: 10, bounciness: 12 }),
|
||||
]).start();
|
||||
}, []);
|
||||
|
||||
const message = getResultMessage(gameType, score);
|
||||
const statLabel = getStatLabel(gameType);
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.container, { opacity: fadeIn }]}>
|
||||
<Text style={styles.title}>Challenge Complete</Text>
|
||||
|
||||
<Animated.View style={[styles.scoreCard, { transform: [{ scale: scaleScore }] }]}>
|
||||
<Text style={styles.scoreLabel}>Score</Text>
|
||||
<Text style={styles.scoreValue}>{score}</Text>
|
||||
<Text style={styles.statBonus}>+{statLabel}</Text>
|
||||
</Animated.View>
|
||||
|
||||
<Text style={styles.message}>{message}</Text>
|
||||
|
||||
{details && (
|
||||
<View style={styles.detailsCard}>
|
||||
{details.avgReaction && (
|
||||
<DetailRow label="Avg Reaction" value={`${details.avgReaction}ms`} />
|
||||
)}
|
||||
{details.rounds && (
|
||||
<DetailRow label="Rounds" value={details.rounds} />
|
||||
)}
|
||||
{details.successes !== undefined && (
|
||||
<DetailRow label="Successes" value={`${details.successes}/${details.rounds}`} />
|
||||
)}
|
||||
{details.perfects !== undefined && (
|
||||
<>
|
||||
<DetailRow label="Perfect" value={details.perfects} color={colors.accent} />
|
||||
<DetailRow label="Good" value={details.goods} color={colors.success} />
|
||||
<DetailRow label="Miss" value={details.misses} color={colors.error} />
|
||||
</>
|
||||
)}
|
||||
{details.correct !== undefined && (
|
||||
<DetailRow label="Correct" value={`${details.correct}/${details.rounds}`} />
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View style={styles.actions}>
|
||||
<Button title="Save & Exit" onPress={onSave} loading={saving} style={styles.btn} />
|
||||
<Button title="Play Again" onPress={onRetry} variant="secondary" style={styles.btn} />
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
function DetailRow({ label, value, color }) {
|
||||
return (
|
||||
<View style={styles.detailRow}>
|
||||
<Text style={styles.detailLabel}>{label}</Text>
|
||||
<Text style={[styles.detailValue, color && { color }]}>{value}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: spacing.lg },
|
||||
title: { color: colors.accent, fontSize: fonts.sizes.xs, fontWeight: fonts.weights.bold, letterSpacing: 3, textTransform: 'uppercase', marginBottom: spacing.xl },
|
||||
scoreCard: {
|
||||
backgroundColor: colors.surface, borderRadius: borderRadius.xl, paddingVertical: spacing.xl, paddingHorizontal: spacing.xxl,
|
||||
alignItems: 'center', borderWidth: 1, borderColor: colors.primary, marginBottom: spacing.lg,
|
||||
shadowColor: colors.primary, shadowOffset: { width: 0, height: 0 }, shadowOpacity: 0.3, shadowRadius: 20, elevation: 8,
|
||||
},
|
||||
scoreLabel: { color: colors.textSecondary, fontSize: fonts.sizes.sm, marginBottom: spacing.xs },
|
||||
scoreValue: { color: colors.text, fontSize: 56, fontWeight: fonts.weights.bold },
|
||||
statBonus: { color: colors.primary, fontSize: fonts.sizes.sm, fontWeight: fonts.weights.semibold, marginTop: spacing.xs },
|
||||
message: { color: colors.text, fontSize: fonts.sizes.md, textAlign: 'center', lineHeight: 24, marginBottom: spacing.xl, paddingHorizontal: spacing.md },
|
||||
detailsCard: {
|
||||
backgroundColor: colors.surface, borderRadius: borderRadius.md, padding: spacing.lg,
|
||||
width: '100%', borderWidth: 1, borderColor: colors.border, marginBottom: spacing.xl,
|
||||
},
|
||||
detailRow: { flexDirection: 'row', justifyContent: 'space-between', paddingVertical: spacing.sm },
|
||||
detailLabel: { color: colors.textSecondary, fontSize: fonts.sizes.sm },
|
||||
detailValue: { color: colors.text, fontSize: fonts.sizes.sm, fontWeight: fonts.weights.semibold },
|
||||
actions: { width: '100%' },
|
||||
btn: { marginBottom: spacing.sm },
|
||||
});
|
||||
Reference in New Issue
Block a user