@@ -0,0 +1,133 @@
|
||||
// Client HTTP vers l'API Omnex.
|
||||
const BASE = import.meta.env.VITE_API_URL ?? 'http://localhost:8080'
|
||||
|
||||
const TOKEN_KEY = 'omnex.token'
|
||||
|
||||
|
||||
export function getToken(): string | null {
|
||||
return localStorage.getItem(TOKEN_KEY)
|
||||
}
|
||||
export function setToken(t: string) {
|
||||
localStorage.setItem(TOKEN_KEY, t)
|
||||
}
|
||||
export function clearToken() {
|
||||
localStorage.removeItem(TOKEN_KEY)
|
||||
}
|
||||
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number
|
||||
constructor(status: number, message: string) {
|
||||
super(message)
|
||||
this.status = status
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
||||
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
|
||||
const token = getToken()
|
||||
if (token) headers.Authorization = `Bearer ${token}`
|
||||
|
||||
const res = await fetch(`${BASE}/api/v1${path}`, {
|
||||
method,
|
||||
headers,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
})
|
||||
if (!res.ok) {
|
||||
const msg = await res.json().catch(() => ({ error: `HTTP ${res.status}` }))
|
||||
throw new ApiError(res.status, msg.error ?? `HTTP ${res.status}`)
|
||||
}
|
||||
return res.status === 204 ? (undefined as T) : ((await res.json()) as T)
|
||||
}
|
||||
|
||||
// --- Types ---
|
||||
|
||||
export type Role = 'admin' | 'client'
|
||||
|
||||
export interface Lead {
|
||||
id: string
|
||||
company: string
|
||||
email: string
|
||||
message: string
|
||||
status: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export type DemoStatus =
|
||||
| 'pending'
|
||||
| 'provisioning'
|
||||
| 'ready'
|
||||
| 'expiring'
|
||||
| 'expired'
|
||||
| 'failed'
|
||||
|
||||
export interface Demo {
|
||||
id: string
|
||||
lead_id?: string
|
||||
status: DemoStatus
|
||||
namespace: string
|
||||
url: string
|
||||
created_at: string
|
||||
expires_at: string
|
||||
}
|
||||
|
||||
export interface CodeBuySub {
|
||||
id: string
|
||||
username: string
|
||||
code_verif: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface Contact {
|
||||
id: string
|
||||
username: string
|
||||
telegram: string
|
||||
sujet: string
|
||||
message: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
// --- Endpoints ---
|
||||
|
||||
export const api = {
|
||||
login: (username: string, password: string) =>
|
||||
request<{ token: string; token_type: string; role: Role }>('POST', '/auth/login', {
|
||||
username,
|
||||
password,
|
||||
}),
|
||||
register: (username: string, password: string) =>
|
||||
request<{ token: string; token_type: string; role: Role }>('POST', '/auth/register', {
|
||||
username,
|
||||
password,
|
||||
}),
|
||||
me: () =>
|
||||
request<{
|
||||
user_id: string
|
||||
username: string
|
||||
role: Role
|
||||
type_abonnement: string
|
||||
expired_at: string
|
||||
}>('GET', '/auth/me'), logout: () => request<{ status: string }>('POST', '/auth/logout'),
|
||||
|
||||
createLead: (telegram: string, message: string) =>
|
||||
request<Lead>('POST', '/leads', { telegram, message }),
|
||||
listLeads: () => request<{ items: Lead[] }>('GET', '/leads'),
|
||||
setLeadStatus: (id: string, status: string) =>
|
||||
request<Lead>('PATCH', `/leads/${id}/status`, { status }),
|
||||
|
||||
listDemos: () => request<{ items: Demo[] }>('GET', '/demos'),
|
||||
getDemo: (id: string) => request<Demo>('GET', `/demos/${id}`),
|
||||
createDemo: (leadId?: string) =>
|
||||
request<Demo>('POST', '/demos', leadId ? { lead_id: leadId } : {}),
|
||||
extendDemo: (id: string) => request<Demo>('POST', `/demos/${id}/extend`),
|
||||
deleteDemo: (id: string) => request<Demo>('DELETE', `/demos/${id}`),
|
||||
|
||||
listCodes: () => request<{ items: CodeBuySub[] }>('GET', '/codes'),
|
||||
createCode: (username: string) =>
|
||||
request<{ code: string }>('POST', '/codes', { username }),
|
||||
addCode: (code: string) =>
|
||||
request<{ success: string }>('POST', '/subscription', { code_verif: code }),
|
||||
sendMessage: (username: string, telegram: string, sujet: string, message: string) =>
|
||||
request<{ success: string }>('POST', '/send/message', { username, telegram, sujet, message }),
|
||||
getMessage: () => request<{ messages: Contact[] }>('GET', '/messages'),
|
||||
}
|
||||
Reference in New Issue
Block a user