import { SafeAreaView } from "react-native-safe-area-context";
import { ui } from "../components/ui/uiStyles";
-import { loadSettings } from "../utils/settingsStorage";
+import { loadSettings, saveSettings } from "../utils/settingsStorage";
import type { UserSettings } from "../models/UserSettings";
import type { StrategyKey, StrategyOption } from "../types/Strategy";
import { fetchStrategies } from "../services/strategyService";
-/**
- * ✅ API-ready (façade)
- * Aujourd'hui : update local settings
- * Demain : POST /api/strategy/select
- */
import { selectStrategy } from "../services/api/strategyApi";
+/**
+ * StrategyScreen
+ * --------------
+ * Maintenant :
+ * - On garde la liste locale (fetchStrategies)
+ * - On sync vers serveur : POST /api/strategy/select
+ * - On met à jour le settings local pour affichage immédiat
+ */
export default function StrategyScreen() {
const [settings, setSettings] = useState<UserSettings | null>(null);
const [strategies, setStrategies] = useState<StrategyOption[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [info, setInfo] = useState<string | null>(null);
+ const [busy, setBusy] = useState<boolean>(false);
useEffect(() => {
let active = true;
const isSelected = (key: StrategyKey) => settings.selectedStrategyKey === key;
const handleSelect = async (key: StrategyKey) => {
- // ✅ Façade : aujourd'hui local, demain API
- const updated = await selectStrategy(key);
-
- setSettings(updated);
- setInfo(`Stratégie sélectionnée : ${key}`);
+ try {
+ setBusy(true);
+ setInfo(null);
+
+ // 1) Update local immédiat (UX + dashboard)
+ const next: UserSettings = { ...settings, selectedStrategyKey: key };
+ await saveSettings(next);
+ setSettings(next);
+
+ // 2) Sync serveur (contrat Stéphane)
+ // Pair cible : pour l’instant BTC/EUR (comme le dashboard). Si vous passez multi-crypto, on l’adaptera.
+ await selectStrategy({
+ pair: "BTC/EUR",
+ mode: key,
+ params: {}, // si un jour tu as des paramètres, tu les mets ici
+ });
+
+ setInfo(`Stratégie sélectionnée : ${key} ✅ (sync serveur OK)`);
+ } catch (e: any) {
+ setInfo(`Erreur serveur stratégie : ${e?.message ?? "inconnue"}`);
+ } finally {
+ setBusy(false);
+ }
};
return (
ui.button,
styles.fullButton,
isSelected(item.key) && styles.btnSelected,
+ busy && styles.btnDisabled,
]}
onPress={() => handleSelect(item.key)}
+ disabled={busy}
>
<Text style={ui.buttonText}>
- {isSelected(item.key) ? "Sélectionnée ✅" : "Sélectionner"}
+ {isSelected(item.key) ? "Sélectionnée ✅" : busy ? "Envoi..." : "Sélectionner"}
</Text>
</TouchableOpacity>
</View>
opacity: 0.9,
},
+ btnDisabled: {
+ opacity: 0.6,
+ },
+
riskTag: {
fontWeight: "900",
opacity: 0.75,
import { apiPost } from "./http";
import { loadSession } from "../../utils/sessionStorage";
-import type { UserSettings } from "../../models/UserSettings";
+import type { StrategyKey } from "../../types/Strategy";
/**
- * strategyApi (API-only)
- * ----------------------
+ * strategyApi (API)
+ * -----------------
+ * Contrat (objectif) :
* POST /api/strategy/select
+ * Body:
+ * {
+ * userId: string,
+ * pair: "BTC/EUR",
+ * mode: "RSI_SIMPLE" | "MA_CROSS" | ...,
+ * params: object
+ * }
+ *
+ * Réponse possible :
+ * - { ok:true, data:{ ... } } (géré par http.ts)
+ * - ou une réponse vide -> on considère que c'est OK si pas d'erreur HTTP
*/
-export async function selectStrategy(strategyKey: string): Promise<UserSettings> {
+export async function selectStrategy(params: {
+ pair: string; // ex: "BTC/EUR"
+ mode: StrategyKey; // ex: "RSI_SIMPLE"
+ params?: Record<string, unknown>;
+}): Promise<void> {
const session = await loadSession();
const userId = session?.userId;
if (!userId) throw new Error("Session absente : impossible de sélectionner une stratégie.");
- // Le backend décidera quoi renvoyer : settings mis à jour ou juste ok.
- // On part sur "settings" pour éviter de recharger partout.
- const data = await apiPost<{ settings: UserSettings }>(`/strategy/select`, {
+ await apiPost(`/strategy/select`, {
userId,
- strategyKey,
+ pair: params.pair,
+ mode: params.mode,
+ params: params.params ?? {},
});
-
- if (!data.settings) throw new Error("Réponse API invalide : settings manquant.");
- return data.settings;
}
\ No newline at end of file