]> git.digitality.be Git - pdw25-26/commitdiff
Mobile : Changement Ui Dashboard
authorThibaud Moustier <thibaudmoustier0@gmail.com>
Wed, 25 Feb 2026 14:54:11 +0000 (15:54 +0100)
committerThibaud Moustier <thibaudmoustier0@gmail.com>
Wed, 25 Feb 2026 14:54:11 +0000 (15:54 +0100)
Wallette/mobile/App.tsx
Wallette/mobile/package-lock.json
Wallette/mobile/package.json
Wallette/mobile/src/screens/DashboardScreen.tsx

index 454050975f5b93cc43864533a11e911a5c82c8e8..c1f7b6fade61c3ff27e11f8518b968fe67e5a3b6 100644 (file)
@@ -1,5 +1,7 @@
 import { NavigationContainer } from "@react-navigation/native";
 import { createNativeStackNavigator } from "@react-navigation/native-stack";
+import { TouchableOpacity, View } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
 
 import DashboardScreen from "./src/screens/DashboardScreen";
 import SettingsScreen from "./src/screens/SettingsScreen";
@@ -7,8 +9,6 @@ import HistoryScreen from "./src/screens/HistoryScreen";
 import AlertsScreen from "./src/screens/AlertsScreen";
 import StrategyScreen from "./src/screens/StrategyScreen";
 
-
-// Types des routes (pour éviter les erreurs de navigation)
 export type RootStackParamList = {
   Dashboard: undefined;
   Settings: undefined;
@@ -26,7 +26,25 @@ export default function App() {
         <Stack.Screen
           name="Dashboard"
           component={DashboardScreen}
-          options={{ title: "Dashboard" }}
+          options={({ navigation }) => ({
+            title: "Dashboard",
+            // ✅ icônes header à droite
+            headerRight: () => (
+              <View style={{ flexDirection: "row", gap: 12 }}>
+                <TouchableOpacity onPress={() => navigation.navigate("Alerts")}>
+                  <Ionicons name="notifications-outline" size={22} color="#0f172a" />
+                </TouchableOpacity>
+
+                <TouchableOpacity onPress={() => navigation.navigate("History")}>
+                  <Ionicons name="time-outline" size={22} color="#0f172a" />
+                </TouchableOpacity>
+
+                <TouchableOpacity onPress={() => navigation.navigate("Settings")}>
+                  <Ionicons name="settings-outline" size={22} color="#0f172a" />
+                </TouchableOpacity>
+              </View>
+            ),
+          })}
         />
 
         <Stack.Screen
@@ -35,24 +53,23 @@ export default function App() {
           options={{ title: "Paramètres" }}
         />
 
-        <Stack.Screen 
-          name="History" 
-          component={HistoryScreen} 
-          options={{ title: "Historique" }} 
+        <Stack.Screen
+          name="History"
+          component={HistoryScreen}
+          options={{ title: "Historique" }}
         />
 
-        <Stack.Screen 
-          name="Alerts" 
-          component={AlertsScreen} 
-          options={{ title: "Alertes" }} 
-          />
-
-        <Stack.Screen 
-          name="Strategy" 
-          component={StrategyScreen} 
-          options={{ title: "Stratégie" }} 
-          />
-        
+        <Stack.Screen
+          name="Alerts"
+          component={AlertsScreen}
+          options={{ title: "Alertes" }}
+        />
+
+        <Stack.Screen
+          name="Strategy"
+          component={StrategyScreen}
+          options={{ title: "Stratégie" }}
+        />
       </Stack.Navigator>
     </NavigationContainer>
   );
index 212ee14f4e4c0569eec8091af248a4e07aed78d8..fd361d289845da2662cb77af19fe9f45703b1cc8 100644 (file)
@@ -8,6 +8,7 @@
       "name": "wall-e-tte",
       "version": "1.0.0",
       "dependencies": {
+        "@expo/vector-icons": "^15.0.3",
         "@react-native-async-storage/async-storage": "2.2.0",
         "@react-navigation/native": "^7.1.28",
         "@react-navigation/native-stack": "^7.13.0",
       "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
       "license": "MIT"
     },
+    "node_modules/@expo/vector-icons": {
+      "version": "15.1.1",
+      "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz",
+      "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==",
+      "license": "MIT",
+      "peerDependencies": {
+        "expo-font": ">=14.0.4",
+        "react": "*",
+        "react-native": "*"
+      }
+    },
     "node_modules/@expo/ws-tunnel": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
         "react-native": "*"
       }
     },
+    "node_modules/expo-font": {
+      "version": "14.0.11",
+      "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz",
+      "integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==",
+      "license": "MIT",
+      "dependencies": {
+        "fontfaceobserver": "^2.1.0"
+      },
+      "peerDependencies": {
+        "expo": "*",
+        "react": "*",
+        "react-native": "*"
+      }
+    },
     "node_modules/expo-modules-autolinking": {
       "version": "3.0.24",
       "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.24.tgz",
         }
       }
     },
-    "node_modules/expo/node_modules/@expo/vector-icons": {
-      "version": "15.0.3",
-      "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz",
-      "integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "expo-font": ">=14.0.4",
-        "react": "*",
-        "react-native": "*"
-      }
-    },
     "node_modules/expo/node_modules/ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
         "react-native": "*"
       }
     },
-    "node_modules/expo/node_modules/expo-font": {
-      "version": "14.0.11",
-      "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz",
-      "integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==",
-      "license": "MIT",
-      "dependencies": {
-        "fontfaceobserver": "^2.1.0"
-      },
-      "peerDependencies": {
-        "expo": "*",
-        "react": "*",
-        "react-native": "*"
-      }
-    },
     "node_modules/expo/node_modules/expo-keep-awake": {
       "version": "15.0.8",
       "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
index 3500e3a73dc14062c483b9120120e3b84c7daee3..0db1739d0bb07caebe29b336277c1a21de80481c 100644 (file)
@@ -9,6 +9,7 @@
     "web": "expo start --web"
   },
   "dependencies": {
+    "@expo/vector-icons": "^15.0.3",
     "@react-native-async-storage/async-storage": "2.2.0",
     "@react-navigation/native": "^7.1.28",
     "@react-navigation/native-stack": "^7.13.0",
index 70649541c12821dcaa395b74c4df6f05f0b648e3..61905ddbacf1f018b7020f5073b829b580c38f54 100644 (file)
@@ -1,5 +1,12 @@
-import { View, Text, StyleSheet, ScrollView } from "react-native";
-import { useState, useCallback, useEffect } from "react";
+import {
+  View,
+  Text,
+  StyleSheet,
+  ScrollView,
+  TouchableOpacity,
+  useWindowDimensions,
+} from "react-native";
+import { useState, useCallback, useEffect, useMemo } from "react";
 import { SafeAreaView } from "react-native-safe-area-context";
 import { useFocusEffect, useNavigation } from "@react-navigation/native";
 
@@ -8,56 +15,41 @@ import { fetchDashboardSummary } from "../services/dashboardService";
 import { loadSettings } from "../utils/settingsStorage";
 import type { UserSettings } from "../models/UserSettings";
 
-import MarketCard from "../components/MarketCard";
-import StrategyCard from "../components/StrategyCard";
-import WalletCard from "../components/WalletCard";
-import ActionsCard from "../components/ActionsCard";
-
 import { ui } from "../components/ui/uiStyles";
 
-// ✅ Socket.IO
 import { socketService } from "../services/socketService";
 import { SERVER_URL } from "../config/env";
 import type { Alert } from "../types/Alert";
-
-// ✅ Store global alertes
 import { alertStore } from "../services/alertStore";
-
-// ✅ Notifications locales Expo
 import { showAlertNotification } from "../services/notificationService";
 
 /**
- * DashboardScreen
- * ----------------
- * Écran principal mobile.
- * - Charge Dashboard + Settings
- * - Refresh auto si activé
- * - Socket.IO non bloquant pour alertes live
- * - Dashboard = résumé : on affiche UNE seule alerte (la dernière)
- *
- * Notifications :
- * - Si settings.notificationsEnabled = true -> notification locale à chaque alerte reçue
+ * DashboardScreen (WF-01) — Responsive
+ * -----------------------------------
+ * Objectif : coller au mockup, éviter le scroll.
+ * - On enlève le gros bloc "Actions" (navigation via header icons)
+ * - Certaines cartes deviennent cliquables (tap-to-open)
  */
 export default function DashboardScreen() {
+  const { height } = useWindowDimensions();
+  const compact = height < 760;
+
   const [summary, setSummary] = useState<DashboardSummary | null>(null);
   const [settings, setSettings] = useState<UserSettings | null>(null);
-  const [loading, setLoading] = useState<boolean>(true);
 
-  // erreurs REST/refresh
+  const [loading, setLoading] = useState<boolean>(true);
   const [error, setError] = useState<string | null>(null);
 
-  // Socket state (non bloquant)
   const [socketConnected, setSocketConnected] = useState<boolean>(false);
   const [socketError, setSocketError] = useState<string | null>(null);
 
-  // Résumé dashboard (dernière alerte reçue affichée)
   const [liveAlerts, setLiveAlerts] = useState<Alert[]>([]);
 
+  const [lastRefreshMs, setLastRefreshMs] = useState<number | null>(null);
+  const [refreshing, setRefreshing] = useState<boolean>(false);
+
   const navigation = useNavigation();
 
-  /**
-   * Chargement initial + rechargement quand on revient sur l'écran
-   */
   useFocusEffect(
     useCallback(() => {
       let isActive = true;
@@ -72,10 +64,11 @@ export default function DashboardScreen() {
             loadSettings(),
           ]);
 
-          if (isActive) {
-            setSummary(dashboardData);
-            setSettings(userSettings);
-          }
+          if (!isActive) return;
+
+          setSummary(dashboardData);
+          setSettings(userSettings);
+          setLastRefreshMs(Date.now());
         } catch {
           if (isActive) setError("Impossible de charger le dashboard.");
         } finally {
@@ -91,9 +84,6 @@ export default function DashboardScreen() {
     }, [])
   );
 
-  /**
-   * Refresh auto (sans clignotement global)
-   */
   useEffect(() => {
     if (!settings) return;
     if (settings.refreshMode !== "auto") return;
@@ -103,7 +93,10 @@ export default function DashboardScreen() {
     const intervalId = setInterval(async () => {
       try {
         const data = await fetchDashboardSummary();
-        if (!cancelled) setSummary(data);
+        if (!cancelled) {
+          setSummary(data);
+          setLastRefreshMs(Date.now());
+        }
       } catch {
         if (!cancelled) setError("Erreur lors du rafraîchissement automatique.");
       }
@@ -115,17 +108,25 @@ export default function DashboardScreen() {
     };
   }, [settings]);
 
-  /**
-   * Socket.IO (non bloquant)
-   * - En Step 1/2/3 on utilise un userId de test (auth pas encore là)
-   * - Si serveur KO, on n'empêche pas l'app de fonctionner
-   */
+  const handleManualRefresh = async () => {
+    try {
+      setRefreshing(true);
+      const data = await fetchDashboardSummary();
+      setSummary(data);
+      setLastRefreshMs(Date.now());
+      setError(null);
+    } catch {
+      setError("Erreur lors de l'actualisation.");
+    } finally {
+      setRefreshing(false);
+    }
+  };
+
   useEffect(() => {
     if (!settings) return;
 
     setSocketError(null);
 
-    // ✅ userId de test pour avancer maintenant
     const userId = "test-user";
 
     try {
@@ -138,15 +139,10 @@ export default function DashboardScreen() {
     }
 
     const unsubscribeAlert = socketService.onAlert((alert) => {
-      // 1) Stock global (écran Alertes)
       alertStore.add(alert);
+      setLiveAlerts((prev) => [alert, ...prev].slice(0, 100));
 
-      // 2) Résumé dashboard (dernière alerte)
-      setLiveAlerts((prev) => [alert, ...prev].slice(0, 50));
-
-      // 3) Notification locale (si activée)
       if (settings.notificationsEnabled) {
-        // On encapsule pour ne jamais casser le thread UI
         void (async () => {
           try {
             await showAlertNotification(alert);
@@ -166,7 +162,18 @@ export default function DashboardScreen() {
     };
   }, [settings]);
 
-  // Chargement
+  const urgentAlert: Alert | null = useMemo(() => {
+    if (liveAlerts.length === 0) return null;
+
+    const critical = liveAlerts.filter((a) => a.alertLevel === "CRITICAL");
+    if (critical.length > 0) return critical[0];
+
+    const warning = liveAlerts.filter((a) => a.alertLevel === "WARNING");
+    if (warning.length > 0) return warning[0];
+
+    return liveAlerts[0];
+  }, [liveAlerts]);
+
   if (loading) {
     return (
       <View style={ui.centered}>
@@ -175,7 +182,6 @@ export default function DashboardScreen() {
     );
   }
 
-  // Erreur bloquante (si rien à afficher)
   if (error && (!summary || !settings)) {
     return (
       <View style={ui.centered}>
@@ -184,7 +190,6 @@ export default function DashboardScreen() {
     );
   }
 
-  // Sécurité
   if (!summary || !settings) {
     return (
       <View style={ui.centered}>
@@ -195,58 +200,130 @@ export default function DashboardScreen() {
 
   return (
     <SafeAreaView style={styles.safeArea}>
-      <ScrollView contentContainerStyle={ui.container}>
-        {/* Bannière warning REST/refresh (non bloquant) */}
+      <ScrollView
+        contentContainerStyle={[ui.container, compact && styles.containerCompact]}
+        showsVerticalScrollIndicator={false}
+      >
         {error && (
-          <View style={[ui.banner, styles.bannerWarning]}>
-            <Text style={[ui.bannerText, styles.bannerWarningText]}>{error}</Text>
+          <View style={[ui.banner, styles.bannerWarning, compact && styles.bannerCompact]}>
+            <Text style={[ui.bannerText, styles.bannerWarningText]} numberOfLines={2}>
+              {error}
+            </Text>
           </View>
         )}
 
-        {/* Bannière Socket (non bloquant) */}
-        <View style={[ui.banner, styles.bannerSocket]}>
-          <Text style={[ui.bannerText, styles.socketTitle]}>
-            Socket.IO : {socketConnected ? "connecté ✅" : "déconnecté ⚠️"}
+        {/* 1) CONSEILLER */}
+        <View style={[ui.card, compact && styles.cardCompact]}>
+          <Text style={[ui.title, compact && styles.titleCompact]}>Conseiller</Text>
+
+          <Text style={[ui.bigCenter, compact && styles.bigCompact]}>{summary.decision}</Text>
+
+          <Text style={[ui.muted, styles.centerText]} numberOfLines={compact ? 2 : 3}>
+            Pourquoi ? {summary.reason}
           </Text>
 
-          {!!socketError && <Text style={ui.muted}>{socketError}</Text>}
-          <Text style={[ui.muted, { marginTop: 4 }]}>
-            Alertes reçues : {liveAlerts.length}
+          <Text style={[ui.muted, { marginTop: compact ? 6 : 10 }]} numberOfLines={1}>
+            Stratégie : <Text style={styles.boldInline}>{settings.selectedStrategyKey}</Text>
           </Text>
+
+          <TouchableOpacity
+            style={[ui.button, styles.fullButton, compact && styles.buttonCompact]}
+            onPress={() => navigation.navigate("Strategy" as never)}
+          >
+            <Text style={ui.buttonText}>Sélectionner stratégie</Text>
+          </TouchableOpacity>
         </View>
 
-        {/* Dashboard : afficher uniquement la DERNIÈRE alerte */}
-        {liveAlerts.length > 0 && (
-          <View style={styles.alertItem}>
-            <Text style={styles.alertHeader}>
-              {liveAlerts[0].alertLevel} — {liveAlerts[0].action}{" "}
-              {liveAlerts[0].pair}
+        {/* 2) PORTEFEUILLE (pas encore cliquable car pas d’écran Wallet dédié) */}
+        <View style={[ui.card, compact && styles.cardCompact]}>
+          <Text style={[ui.title, compact && styles.titleCompact]}>Portefeuille</Text>
+
+          <View style={ui.rowBetween}>
+            <Text style={ui.value}>Valeur Totale :</Text>
+            <Text style={ui.valueBold}>10 000 {settings.currency}</Text>
+          </View>
+
+          {!compact && (
+            <Text style={[ui.muted, { marginTop: 6 }]}>
+              Step 1 : mono-utilisateur / mono-crypto
             </Text>
-            <Text style={styles.alertBody}>
-              {(liveAlerts[0].confidence * 100).toFixed(0)}% —{" "}
-              {liveAlerts[0].reason}
+          )}
+        </View>
+
+        {/* 3) URGENCE — cliquable => Alertes */}
+        <TouchableOpacity
+          activeOpacity={0.85}
+          onPress={() => navigation.navigate("Alerts" as never)}
+        >
+          <View style={[ui.card, compact && styles.cardCompact]}>
+            <Text style={[ui.title, compact && styles.titleCompact]}>Urgence</Text>
+
+            {urgentAlert ? (
+              <View style={[styles.urgentBox, compact && styles.urgentBoxCompact]}>
+                <Text style={styles.urgentTitle} numberOfLines={2}>
+                  {urgentAlert.alertLevel} : {urgentAlert.reason}
+                </Text>
+                <Text style={ui.muted} numberOfLines={1}>
+                  {urgentAlert.action} {urgentAlert.pair} —{" "}
+                  {(urgentAlert.confidence * 100).toFixed(0)}%
+                </Text>
+              </View>
+            ) : (
+              <Text style={ui.muted}>Aucune alerte pour le moment.</Text>
+            )}
+
+            <Text style={[ui.muted, { marginTop: compact ? 6 : 8 }]} numberOfLines={1}>
+              Socket : {socketConnected ? "connecté ✅" : "déconnecté ⚠️"}
+              {socketError ? ` — ${socketError}` : ""}
             </Text>
-            <Text style={styles.alertHint}>
-              Voir toutes les alertes dans “Alertes”.
+
+            <Text style={[ui.muted, { marginTop: 6 }]} numberOfLines={1}>
+              Appuie pour ouvrir “Alertes”
             </Text>
           </View>
-        )}
+        </TouchableOpacity>
+
+        {/* 4) PRIX BTC — cliquable => Historique */}
+        <TouchableOpacity
+          activeOpacity={0.85}
+          onPress={() => navigation.navigate("History" as never)}
+        >
+          <View style={[ui.card, compact && styles.cardCompact]}>
+            <View style={styles.priceHeaderRow}>
+              <Text style={[ui.title, compact && styles.titleCompact]}>Prix BTC</Text>
+
+              <TouchableOpacity
+                style={[
+                  styles.refreshBtn,
+                  refreshing && styles.refreshBtnDisabled,
+                  compact && styles.refreshBtnCompact,
+                ]}
+                onPress={handleManualRefresh}
+                disabled={refreshing}
+              >
+                <Text style={styles.refreshBtnText}>{refreshing ? "…" : "Actualiser"}</Text>
+              </TouchableOpacity>
+            </View>
+
+            <Text style={ui.muted} numberOfLines={1}>
+              Dernière maj :{" "}
+              {lastRefreshMs ? new Date(lastRefreshMs).toLocaleTimeString() : "—"}
+            </Text>
 
-        <MarketCard summary={summary} settings={settings} />
-        
-        <StrategyCard
-          summary={summary}
-          settings={settings}
-          onGoStrategy={() => navigation.navigate("Strategy" as never)}
-        />
-
-        <WalletCard settings={settings} />
-
-        <ActionsCard
-          onGoSettings={() => navigation.navigate("Settings" as never)}
-          onGoHistory={() => navigation.navigate("History" as never)}
-          onGoAlerts={() => navigation.navigate("Alerts" as never)}
-        />
+            <View style={[styles.priceCard, compact && styles.priceCardCompact]}>
+              <View style={ui.rowBetween}>
+                <Text style={ui.value}>Prix BTC</Text>
+                <Text style={styles.priceBig}>
+                  {summary.price.toFixed(2)} {settings.currency}
+                </Text>
+              </View>
+            </View>
+
+            <Text style={[ui.muted, { marginTop: 6 }]} numberOfLines={1}>
+              Appuie pour ouvrir “Historique”
+            </Text>
+          </View>
+        </TouchableOpacity>
       </ScrollView>
     </SafeAreaView>
   );
@@ -258,9 +335,22 @@ const styles = StyleSheet.create({
     backgroundColor: ui.screen.backgroundColor,
   },
 
-  errorText: {
-    color: "#dc2626",
-    fontWeight: "900",
+  containerCompact: {
+    padding: 12,
+  },
+
+  cardCompact: {
+    padding: 12,
+    marginBottom: 10,
+  },
+
+  titleCompact: {
+    marginBottom: 6,
+  },
+
+  bigCompact: {
+    fontSize: 24,
+    marginVertical: 4,
   },
 
   bannerWarning: {
@@ -269,34 +359,90 @@ const styles = StyleSheet.create({
   bannerWarningText: {
     color: "#ca8a04",
   },
+  bannerCompact: {
+    padding: 10,
+    marginBottom: 10,
+  },
 
-  bannerSocket: {
-    borderColor: "#cbd5e1",
+  errorText: {
+    color: "#dc2626",
+    fontWeight: "900",
   },
-  socketTitle: {
+
+  centerText: {
+    textAlign: "center",
+  },
+
+  boldInline: {
+    fontWeight: "900",
     color: "#0f172a",
   },
 
-  // Dernière alerte affichée (résumé)
-  alertItem: {
+  fullButton: {
+    flexGrow: 0,
+    flexBasis: "auto",
+    width: "100%",
+    marginTop: 12,
+  },
+  buttonCompact: {
+    paddingVertical: 10,
+    marginTop: 10,
+  },
+
+  urgentBox: {
     borderWidth: 1,
     borderColor: "#e5e7eb",
-    padding: 10,
     borderRadius: 10,
-    marginBottom: 12,
+    padding: 10,
     backgroundColor: "#ffffff",
   },
-  alertHeader: {
+  urgentBoxCompact: {
+    padding: 8,
+  },
+  urgentTitle: {
     fontWeight: "900",
     color: "#0f172a",
   },
-  alertBody: {
-    marginTop: 4,
-    color: "#334155",
+
+  priceHeaderRow: {
+    flexDirection: "row",
+    justifyContent: "space-between",
+    alignItems: "center",
+    marginBottom: 8,
+  },
+  refreshBtn: {
+    paddingHorizontal: 12,
+    paddingVertical: 8,
+    borderRadius: 10,
+    borderWidth: 1,
+    borderColor: "#e5e7eb",
+    backgroundColor: "#fff",
+  },
+  refreshBtnCompact: {
+    paddingVertical: 6,
+  },
+  refreshBtnDisabled: {
+    opacity: 0.6,
+  },
+  refreshBtnText: {
+    fontWeight: "900",
+    color: "#0f172a",
   },
-  alertHint: {
-    marginTop: 6,
-    fontSize: 12,
-    opacity: 0.7,
+
+  priceCard: {
+    marginTop: 10,
+    borderWidth: 1,
+    borderColor: "#e5e7eb",
+    borderRadius: 10,
+    padding: 12,
+    backgroundColor: "#ffffff",
+  },
+  priceCardCompact: {
+    paddingVertical: 10,
+  },
+  priceBig: {
+    fontSize: 22,
+    fontWeight: "900",
+    color: "#0f172a",
   },
 });
\ No newline at end of file