CoolFace
Apppublic

Bineta123/Domainexpert-api

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
home.html300 linesDownload Raw Back to root
1<!DOCTYPE html>
2<html lang="fr">
3<head>
4  <meta charset="UTF-8">
5  <title>🛒 {{ app_name if app_name else "Catégorisation de produits Auchan" }} — Accueil</title>
6  <meta name="viewport" content="width=device-width, initial-scale=1">
7
8  <style>
9    :root{
10      --primary:#0d47a1;
11      --primary2:#1e88e5;
12      --bgGlass: rgba(255,255,255,0.92);
13      --shadow: 0 10px 25px rgba(0,0,0,0.12);
14      --radius: 18px;
15      --success:#1b5e20;
16      --danger:#b71c1c;
17      --warn:#e65100;
18    }
19
20    body{
21      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
22      background-image: url("{{ background_image }}");
23      background-size: cover;
24      background-attachment: fixed;
25      color:#222;
26      padding: 20px;
27      margin: 0;
28    }
29
30    .container{ max-width: 1100px; margin: 0 auto; }
31
32    /* NAVBAR */
33    .nav{
34      background: var(--bgGlass);
35      border-radius: var(--radius);
36      box-shadow: var(--shadow);
37      border: 1px solid rgba(255,255,255,0.6);
38      backdrop-filter: blur(6px);
39      padding: 12px 14px;
40      margin-bottom: 14px;
41
42      display:flex;
43      align-items:center;
44      justify-content: space-between;
45      gap: 10px;
46      flex-wrap: wrap;
47    }
48    .brand{
49      display:flex;
50      align-items:center;
51      gap:10px;
52      font-weight: 900;
53      color: var(--primary);
54      text-decoration: none;
55    }
56    .brand .dot{
57      width: 10px; height: 10px; border-radius: 50%;
58      background: linear-gradient(90deg, var(--primary2), #42a5f5);
59      box-shadow: 0 6px 14px rgba(66,165,245,0.35);
60    }
61    .navlinks{
62      display:flex;
63      gap: 10px;
64      flex-wrap: wrap;
65      align-items: center;
66    }
67    .navlinks a{
68      text-decoration:none;
69      font-weight: 800;
70      color: var(--primary);
71      padding: 8px 10px;
72      border-radius: 12px;
73      border: 1px solid rgba(13,71,161,0.12);
74      background: rgba(13,71,161,0.06);
75      transition: 0.15s;
76    }
77    .navlinks a:hover{ transform: translateY(-1px); }
78    .navlinks a.active{
79      color: #fff;
80      border-color: transparent;
81      background: linear-gradient(90deg, var(--primary2), #42a5f5);
82    }
83
84    .hero{
85      background: var(--bgGlass);
86      padding: 22px;
87      border-radius: var(--radius);
88      box-shadow: var(--shadow);
89      border: 1px solid rgba(255,255,255,0.6);
90      backdrop-filter: blur(6px);
91      margin-bottom: 16px;
92    }
93    .hero h1{
94      margin: 0 0 6px 0;
95      color: var(--primary);
96      text-shadow: 1px 1px 2px #ffffffaa;
97      font-size: 28px;
98    }
99    .hero p{
100      margin: 0;
101      color:#333;
102      line-height: 1.5;
103    }
104
105    .pill{
106      display:inline-block;
107      padding: 6px 10px;
108      border-radius: 999px;
109      background: rgba(13,71,161,0.08);
110      color: var(--primary);
111      font-weight: 800;
112      font-size: 12px;
113      border: 1px solid rgba(13,71,161,0.15);
114    }
115
116    .grid{
117      display: grid;
118      grid-template-columns: 1fr 1fr 1fr;
119      gap: 14px;
120      margin-bottom: 14px;
121    }
122
123    .card{
124      background: var(--bgGlass);
125      padding: 16px;
126      border-radius: var(--radius);
127      box-shadow: var(--shadow);
128      border: 1px solid rgba(255,255,255,0.6);
129      backdrop-filter: blur(6px);
130    }
131
132    .card h2{
133      margin: 0 0 8px 0;
134      color: var(--primary);
135      font-size: 18px;
136    }
137
138    .muted{ color:#555; font-size: 13px; line-height:1.45; }
139
140    .btnRow{
141      margin-top: 12px;
142      display:flex;
143      gap:10px;
144      flex-wrap: wrap;
145      align-items:center;
146    }
147
148    .btn{
149      padding: 11px 16px;
150      background: linear-gradient(90deg, var(--primary2), #42a5f5);
151      color: #fff;
152      border: none;
153      border-radius: 12px;
154      cursor: pointer;
155      font-weight: 800;
156      text-decoration: none;
157      display:inline-block;
158      transition: 0.2s;
159    }
160    .btn:hover{ transform: translateY(-1px); }
161
162    .btn.secondary{
163      background: #ffffff;
164      color: var(--primary);
165      border: 1px solid #bbdefb;
166      font-weight: 800;
167    }
168
169    .statusBox{
170      background: rgba(255,255,255,0.75);
171      border: 1px solid rgba(0,0,0,0.08);
172      border-radius: 14px;
173      padding: 12px;
174      margin-top: 12px;
175    }
176    .ok{ color: var(--success); font-weight: 900; }
177    .err{ color: var(--danger); font-weight: 900; }
178    .warn{ color: var(--warn); font-weight: 900; }
179
180    @media(max-width: 980px){
181      .grid{ grid-template-columns: 1fr; }
182      .nav{ justify-content: center; }
183    }
184  </style>
185</head>
186
187<body>
188<div class="container">
189
190  <!-- NAV -->
191  <div class="nav">
192    <a class="brand" href="/">
193      <span class="dot"></span>
194      <span>{{ app_name if app_name else "Catégorisation de produits Auchan" }}</span>
195    </a>
196
197    <div class="navlinks">
198      <a href="/" class="active">Accueil</a>
199      <a href="/playground">Playground</a>
200      <a href="/leaderboard">Leaderboard</a>
201      <a href="/project">Projet</a>
202    </div>
203  </div>
204
205  <!-- HERO -->
206  <div class="hero">
207    <h1>🛒 {{ app_name if app_name else "Catégorisation de produits Auchan" }}</h1>
208    <p>
209      Application de catégorisation e-commerce basée sur un <b>Domain Expert (XLM-R)</b> et une
210      <b>vérification LLM</b> (optionnelle) pour améliorer les cas ambigus.
211      <span class="pill" style="margin-left:8px;">Sortie = 1 catégorie finale</span>
212    </p>
213
214    <div class="statusBox" style="margin-top:14px;">
215      <div class="muted" style="margin-bottom:6px;"><b>Statut système</b> (auto)</div>
216      <div id="sysStatus" class="muted">Chargement…</div>
217    </div>
218
219    <div class="btnRow">
220      <a class="btn" href="/playground">🚀 Ouvrir le Playground</a>
221      <a class="btn secondary" href="/leaderboard">🏆 Voir le Leaderboard</a>
222      <a class="btn secondary" href="/project">📌 Lire le Projet</a>
223    </div>
224  </div>
225
226  <!-- QUICK CARDS -->
227  <div class="grid">
228    <div class="card">
229      <h2>🎛️ Playground</h2>
230      <div class="muted">
231        Tester la catégorisation sur <b>texte</b>, <b>image</b>, ou en <b>batch CSV</b>.
232        L’API renvoie uniquement la <b>catégorie finale</b>.
233      </div>
234      <div class="btnRow">
235        <a class="btn" href="/playground">Aller au Playground</a>
236      </div>
237    </div>
238
239    <div class="card">
240      <h2>🏆 Leaderboard</h2>
241      <div class="muted">
242        Comparer les modèles (Domain Expert vs Dual Expert) avec un <b>score composite</b> :
243        0.5·F1 + 0.3·Acc + 0.2·Top-10.
244      </div>
245      <div class="btnRow">
246        <a class="btn" href="/leaderboard">Ouvrir le Leaderboard</a>
247      </div>
248    </div>
249
250    <div class="card">
251      <h2>📌 Projet</h2>
252      <div class="muted">
253        Description du pipeline, objectifs, workflow, tâches et livrables (reproduction du Dual-Expert).
254      </div>
255      <div class="btnRow">
256        <a class="btn" href="/project">Voir la page Projet</a>
257      </div>
258    </div>
259  </div>
260
261  <div class="card">
262    <h2>🔌 Endpoints API</h2>
263    <div class="muted">
264      <span class="pill">POST</span> /api/predict (JSON: {"text": ...}) &nbsp;
265      <span class="pill">POST</span> /api/predict_image (form-data: file) &nbsp;
266      <span class="pill">POST</span> /api/predict_batch (form-data: csv_file) &nbsp;
267      <span class="pill">GET</span> /api/export.csv &nbsp;
268      <span class="pill">GET</span> /api/leaderboard
269    </div>
270  </div>
271
272</div>
273
274<script>
275  async function loadStatus(){
276    const el = document.getElementById("sysStatus");
277    try{
278      const r = await fetch("/api/ping");
279      const d = await r.json();
280      if(!r.ok) throw new Error(d.error || "Erreur /api/ping");
281
282      const ready = d.model_ready ? "✅ prêt" : "⏳ non chargé";
283      const key = d.has_openai_key ? "✅ OK" : "⚠️ absente";
284      const device = d.device || "—";
285
286      el.innerHTML = `
287        Modèle : <b>${ready}</b> &nbsp;•&nbsp;
288        OpenAI key : <b>${key}</b> &nbsp;•&nbsp;
289        Device : <b>${device}</b>
290      `;
291    }catch(e){
292      el.innerHTML = `<span class="err">❌ ${e.message}</span>`;
293    }
294  }
295  loadStatus();
296</script>
297
298</body>
299</html>
300