--- /dev/null
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+
+type Props = {
+ onGoSettings: () => void;
+};
+
+export default function ActionsCard({ onGoSettings }: Props) {
+ return (
+ <View style={styles.card}>
+ <Text style={styles.sectionTitle}>Actions</Text>
+
+ <View style={styles.row}>
+ <TouchableOpacity style={styles.button}>
+ <Text style={styles.buttonText}>Voir stratégie</Text>
+ </TouchableOpacity>
+
+ <TouchableOpacity style={styles.button}>
+ <Text style={styles.buttonText}>Historique</Text>
+ </TouchableOpacity>
+
+ <TouchableOpacity style={styles.button} onPress={onGoSettings}>
+ <Text style={styles.buttonText}>Paramètres</Text>
+ </TouchableOpacity>
+ </View>
+ </View>
+ );
+}
+
+const styles = StyleSheet.create({
+ card: {
+ borderWidth: 1,
+ borderColor: "#aaa",
+ padding: 12,
+ marginBottom: 12,
+ borderRadius: 6,
+ },
+ sectionTitle: {
+ fontWeight: "bold",
+ marginBottom: 6,
+ fontSize: 16,
+ },
+ row: {
+ flexDirection: "row",
+ flexWrap: "wrap",
+ gap: 8,
+ },
+ button: {
+ backgroundColor: "#555",
+ paddingHorizontal: 10,
+ paddingVertical: 10,
+ borderRadius: 4,
+ flexGrow: 1,
+ flexBasis: "48%",
+ alignItems: "center",
+ },
+ buttonText: {
+ color: "#fff",
+ fontWeight: "bold",
+ },
+});
\ No newline at end of file
--- /dev/null
+import { View, Text, StyleSheet } from "react-native";
+import type { DashboardSummary } from "../types/DashboardSummary";
+import type { UserSettings } from "../models/UserSettings";
+import { ui } from "./ui/uiStyles";
+
+type Props = {
+ summary: DashboardSummary;
+ settings: UserSettings;
+};
+
+export default function MarketCard({ summary, settings }: Props) {
+ return (
+ <View style={ui.card}>
+ <Text style={ui.title}>Marché</Text>
+
+ <Text style={ui.bigCenter}>{summary.pair}</Text>
+
+ <View style={ui.rowBetween}>
+ <Text style={ui.value}>Prix actuel</Text>
+ <Text style={ui.valueBold}>
+ {summary.price.toFixed(2)} {settings.currency}
+ </Text>
+ </View>
+
+ <Text style={ui.muted}>
+ Dernière mise à jour : {new Date(summary.timestamp).toLocaleString()}
+ </Text>
+ </View>
+ );
+}
+
+const styles = StyleSheet.create({
+ card: {
+ borderWidth: 1,
+ borderColor: "#aaa",
+ padding: 12,
+ marginBottom: 12,
+ borderRadius: 6,
+ },
+ sectionTitle: {
+ fontWeight: "bold",
+ marginBottom: 6,
+ fontSize: 16,
+ },
+ price: {
+ fontSize: 26,
+ fontWeight: "bold",
+ textAlign: "center",
+ marginVertical: 6,
+ },
+ priceRow: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ marginVertical: 4,
+ },
+ value: {
+ fontSize: 16,
+ },
+ valueBold: {
+ fontSize: 16,
+ fontWeight: "bold",
+ },
+ updated: {
+ fontSize: 12,
+ opacity: 0.6,
+ marginTop: 6,
+ textAlign: "center",
+ },
+});
\ No newline at end of file
--- /dev/null
+import { View, Text } from "react-native";
+import type {
+ DashboardSummary,
+ TradeDecision,
+ AlertLevel,
+} from "../types/DashboardSummary";
+import { ui } from "./ui/uiStyles";
+
+type Props = {
+ summary: DashboardSummary;
+};
+
+function getDecisionColor(decision: TradeDecision): string {
+ switch (decision) {
+ case "BUY":
+ return "#16a34a";
+ case "SELL":
+ return "#dc2626";
+ case "STOP_LOSS":
+ return "#991b1b";
+ case "HOLD":
+ default:
+ return "#ca8a04";
+ }
+}
+
+function getAlertColor(level: AlertLevel): string {
+ switch (level) {
+ case "CRITICAL":
+ return "#b91c1c";
+ case "WARNING":
+ return "#ca8a04";
+ case "INFO":
+ default:
+ return "#2563eb";
+ }
+}
+
+/**
+ * StrategyCard
+ * ------------
+ * Affiche la stratégie + décision (BUY/SELL/HOLD/STOP_LOSS)
+ * + niveau d'alerte (CRITICAL/WARNING/INFO)
+ * + confiance et raison.
+ *
+ * Les enums sont affichés en badges ("pill") pour être lisibles sur mobile.
+ */
+export default function StrategyCard({ summary }: Props) {
+ const decisionColor = getDecisionColor(summary.decision);
+ const alertColor = getAlertColor(summary.alertLevel);
+
+ return (
+ <View style={ui.card}>
+ <Text style={ui.title}>Stratégie</Text>
+
+ <Text style={ui.valueBold}>{summary.strategy}</Text>
+
+ {/* Badge décision */}
+ <View style={[ui.badge, { backgroundColor: `${decisionColor}22` }]}>
+ <Text style={[ui.badgeText, { color: decisionColor }]}>
+ {summary.decision}
+ </Text>
+ </View>
+
+ {/* Badge niveau d'alerte */}
+ <View style={[ui.badge, { backgroundColor: `${alertColor}22` }]}>
+ <Text style={[ui.badgeText, { color: alertColor }]}>
+ {summary.alertLevel}
+ </Text>
+ </View>
+
+ <View style={[ui.rowBetween, { marginTop: 10 }]}>
+ <Text style={ui.value}>Confiance</Text>
+ <Text style={ui.valueBold}>
+ {(summary.confidence * 100).toFixed(1)} %
+ </Text>
+ </View>
+
+ <Text style={[ui.muted, { marginTop: 8 }]}>{summary.reason}</Text>
+ </View>
+ );
+}
\ No newline at end of file
--- /dev/null
+import { View, Text, StyleSheet } from "react-native";
+import type { UserSettings } from "../models/UserSettings";
+
+type Props = {
+ settings: UserSettings;
+};
+
+export default function WalletCard({ settings }: Props) {
+ return (
+ <View style={styles.card}>
+ <Text style={styles.sectionTitle}>Portefeuille</Text>
+
+ <View style={styles.priceRow}>
+ <Text style={styles.value}>Valeur totale</Text>
+ <Text style={styles.valueBold}>10 000 {settings.currency}</Text>
+ </View>
+
+ <Text style={styles.updated}>Step 1 : mono-utilisateur / mono-crypto</Text>
+ </View>
+ );
+}
+
+const styles = StyleSheet.create({
+ card: {
+ borderWidth: 1,
+ borderColor: "#aaa",
+ padding: 12,
+ marginBottom: 12,
+ borderRadius: 6,
+ },
+ sectionTitle: {
+ fontWeight: "bold",
+ marginBottom: 6,
+ fontSize: 16,
+ },
+ priceRow: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ marginVertical: 4,
+ },
+ value: {
+ fontSize: 16,
+ },
+ valueBold: {
+ fontSize: 16,
+ fontWeight: "bold",
+ },
+ updated: {
+ fontSize: 12,
+ opacity: 0.6,
+ marginTop: 6,
+ textAlign: "center",
+ },
+});
\ No newline at end of file
--- /dev/null
+import { StyleSheet } from "react-native";
+
+export const ui = StyleSheet.create({
+ screen: {
+ backgroundColor: "#f6f7fb",
+ },
+
+ card: {
+ backgroundColor: "#fff",
+ borderRadius: 14,
+ padding: 14,
+ marginBottom: 12,
+
+ // ombre iOS
+ shadowColor: "#000",
+ shadowOpacity: 0.08,
+ shadowRadius: 10,
+ shadowOffset: { width: 0, height: 4 },
+
+ // ombre Android
+ elevation: 3,
+ },
+
+ title: {
+ fontSize: 16,
+ fontWeight: "700",
+ marginBottom: 10,
+ },
+
+ muted: {
+ opacity: 0.65,
+ fontSize: 12,
+ },
+
+ rowBetween: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ },
+
+ value: {
+ fontSize: 16,
+ },
+
+ valueBold: {
+ fontSize: 16,
+ fontWeight: "700",
+ },
+
+ bigCenter: {
+ fontSize: 28,
+ fontWeight: "800",
+ textAlign: "center",
+ marginVertical: 6,
+ },
+
+ badge: {
+ alignSelf: "center",
+ paddingHorizontal: 12,
+ paddingVertical: 6,
+ borderRadius: 999,
+ marginTop: 6,
+ },
+
+ badgeText: {
+ fontWeight: "800",
+ fontSize: 12,
+ letterSpacing: 0.3,
+ },
+
+ button: {
+ backgroundColor: "#111827",
+ paddingVertical: 12,
+ borderRadius: 12,
+ alignItems: "center",
+ flexGrow: 1,
+ flexBasis: "48%",
+ },
+
+ buttonText: {
+ color: "#fff",
+ fontWeight: "800",
+ },
+});
\ No newline at end of file