chore: build

This commit is contained in:
2026-06-09 19:57:56 +02:00
parent 72c8003acf
commit 7262d44f5a
7 changed files with 341 additions and 48 deletions
+82 -20
View File
@@ -1,7 +1,3 @@
// ============================================
// api/api.ts - VERSION CORRIGÉE
// ============================================
const API_URL = "/api/v1";
const BACKEND_URL = "";
export function getMediaUrl(url: string): string {
@@ -26,17 +22,11 @@ import type {
CancelCommandResponse,
PenaltiesResponse,
} from "./api_types";
// ============================================
// 🔐 TYPES - AUTHRESPONSE COMPLETE
// ============================================
/**
* ✅ TYPE CORRECT - Inclut access_token!
*/
export interface AuthResponse {
success: boolean;
message?: string;
access_token?: string; // ✅ CRITICAL!
access_token?: string;
token_type?: string;
expires_in?: number;
requires_2fa?: boolean;
@@ -53,17 +43,8 @@ export interface AuthResponse {
};
}
// ============================================
// 🔐 GESTION CENTRALISÉE DU JWT
// ============================================
/**
* ✅ Extraire username du JWT
* Source de vérité UNIQUE pour le username
*/
export const extractUsernameFromToken = (): string | null => {
try {
// ✅ CRITICAL: sessionStorage (pas localStorage!)
const token = sessionStorage.getItem("token");
if (!token) {
@@ -2152,3 +2133,84 @@ export const unlinkTelegram = async (): Promise<void> => {
/* silencieux */
}
};
// ============================================
// 🏆 POINTS — RÉCOMPENSES
// ============================================
export type RewardCategoryConfig = {
category: string;
all_products: boolean;
product_ids: number[];
amount: number;
};
export type PointsPoolInfo = {
key: string;
name: string;
points: number;
rewards_earned: number;
rewards_claimed: number;
rewards_available: number;
eligible_configs: RewardCategoryConfig[];
};
export type PointsRewardConfig = {
threshold: number;
type: string;
description: string;
};
export const getMyPointsRewards = async (): Promise<{
success: boolean;
enabled: boolean;
pools: PointsPoolInfo[];
reward: PointsRewardConfig | null;
}> => {
const token = getAuthToken();
if (!token) return { success: false, enabled: false, pools: [], reward: null };
try {
const response = await fetch(`${API_URL}/points/rewards`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) return { success: false, enabled: false, pools: [], reward: null };
const data = await safeJson(response);
return {
success: true,
enabled: data.enabled ?? false,
pools: data.pools ?? [],
reward: data.reward ?? null,
};
} catch {
return { success: false, enabled: false, pools: [], reward: null };
}
};
export const claimMyReward = async (poolKey: string): Promise<{
success: boolean;
description?: string;
remaining_rewards?: number;
error?: string;
}> => {
const token = getAuthToken();
if (!token) return { success: false, error: "Non authentifié" };
try {
const response = await fetch(`${API_URL}/points/claim`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ pool_key: poolKey }),
});
const data = await safeJson(response);
if (!response.ok) return { success: false, error: data.error || "Erreur" };
return {
success: true,
description: data.description,
remaining_rewards: data.remaining_rewards,
};
} catch {
return { success: false, error: "Erreur de connexion" };
}
};
+2 -10
View File
@@ -4,13 +4,6 @@
// Interfaces complètes pour le frontend
// À importer dans les composants
// ============================================
// 🔐 AUTHENTIFICATION - TYPES
// ============================================
/**
* Réponse générique de l'API
*/
export interface ApiResponse {
success: boolean;
message?: string;
@@ -19,8 +12,7 @@ export interface ApiResponse {
token_type?: string;
expires_in?: number;
user?: UserResponse;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any; // Pour les champs additionnels
[key: string]: unknown;
}
/**
@@ -779,6 +771,6 @@ export interface ConfirmReceptionResponse {
category?: string;
points_earned?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
[key: string]: any;
};
}