| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <title>SafeSpace API Test</title> |
| <style> |
| :root { |
| --bg: #0f1a16; |
| --panel: #16231f; |
| --accent: #4fd1a5; |
| --accent-2: #7ce3c3; |
| --text: #e8f6f1; |
| --muted: #9bb7ad; |
| --danger: #f87171; |
| --border: #274136; |
| } |
| |
| * { box-sizing: border-box; } |
| |
| body { |
| margin: 0; |
| font-family: "Space Grotesk", "Figtree", "Montserrat", sans-serif; |
| background: radial-gradient(circle at 15% 10%, #193229, #0f1a16 55%); |
| color: var(--text); |
| } |
| |
| header { |
| padding: 32px 24px 16px; |
| text-align: center; |
| } |
| |
| header h1 { |
| margin: 0 0 8px; |
| font-size: 30px; |
| letter-spacing: 0.4px; |
| } |
| |
| header p { |
| margin: 0; |
| color: var(--muted); |
| } |
| |
| main { |
| max-width: 980px; |
| margin: 0 auto; |
| padding: 24px; |
| display: grid; |
| gap: 18px; |
| } |
| |
| .panel { |
| background: var(--panel); |
| border: 1px solid var(--border); |
| border-radius: 18px; |
| padding: 20px; |
| box-shadow: 0 14px 34px rgba(0, 0, 0, 0.25); |
| } |
| |
| label { |
| display: block; |
| font-size: 13px; |
| text-transform: uppercase; |
| letter-spacing: 1.5px; |
| color: var(--muted); |
| margin-bottom: 8px; |
| } |
| |
| input, textarea { |
| width: 100%; |
| padding: 12px 14px; |
| border-radius: 12px; |
| border: 1px solid var(--border); |
| background: #0c1512; |
| color: var(--text); |
| font-size: 15px; |
| } |
| |
| textarea { min-height: 120px; resize: vertical; } |
| |
| .row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } |
| |
| button { |
| border: none; |
| background: linear-gradient(120deg, var(--accent), var(--accent-2)); |
| color: #062318; |
| font-weight: 700; |
| font-size: 15px; |
| padding: 12px 18px; |
| border-radius: 12px; |
| cursor: pointer; |
| transition: transform 0.2s ease, box-shadow 0.2s ease; |
| width: 100%; |
| } |
| |
| button:hover { transform: translateY(-1px); box-shadow: 0 10px 18px rgba(79, 209, 165, 0.2); } |
| |
| pre { |
| white-space: pre-wrap; |
| word-break: break-word; |
| background: #0b1512; |
| border: 1px solid #1f352d; |
| border-radius: 12px; |
| padding: 16px; |
| min-height: 120px; |
| } |
| |
| .error { color: var(--danger); font-weight: 600; } |
| </style> |
| </head> |
| <body> |
| <header> |
| <h1>SafeSpace API Test</h1> |
| <p>Quickly validate AI endpoints on your Hugging Face Space.</p> |
| </header> |
|
|
| <main> |
| <section class="panel"> |
| <div class="row"> |
| <div> |
| <label for="baseUrl">Base URL</label> |
| <input id="baseUrl" value="https://AliSakr9997-safespace.hf.space" /> |
| </div> |
| <div> |
| <label for="userId">User ID</label> |
| <input id="userId" value="1" /> |
| </div> |
| </div> |
| </section> |
|
|
| <section class="panel"> |
| <label for="textInput">User Text</label> |
| <textarea id="textInput">I have been feeling overwhelmed at work and can't sleep.</textarea> |
| </section> |
|
|
| <section class="panel"> |
| <label for="survey">Survey Answers (42 values, 0-4, comma-separated)</label> |
| <textarea id="survey">0,1,2,1,0,2,1,0,1,2,1,0,2,1,0,2,1,1,0,2,1,2,1,0,2,1,0,1,2,1,0,2,1,0,1,2,1,0,2,1,0,1</textarea> |
| </section> |
|
|
| <section class="panel"> |
| <div class="row"> |
| <button id="analyzeBtn">POST /v1/analysis</button> |
| <button id="historyBtn">GET /v1/users/{id}/analyses</button> |
| </div> |
| </section> |
|
|
| <section class="panel"> |
| <label>Response</label> |
| <pre id="output">Waiting for request...</pre> |
| </section> |
| </main> |
|
|
| <script> |
| const output = document.getElementById('output'); |
| const baseUrl = document.getElementById('baseUrl'); |
| const userId = document.getElementById('userId'); |
| const textInput = document.getElementById('textInput'); |
| const survey = document.getElementById('survey'); |
| |
| function setOutput(data, isError = false) { |
| if (isError) { |
| output.innerHTML = '<span class="error">' + data + '</span>'; |
| } else { |
| output.textContent = typeof data === 'string' ? data : JSON.stringify(data, null, 2); |
| } |
| } |
| |
| function parseSurvey() { |
| return survey.value |
| .split(',') |
| .map((v) => parseInt(v.trim(), 10)) |
| .filter((v) => Number.isFinite(v)); |
| } |
| |
| document.getElementById('analyzeBtn').addEventListener('click', async () => { |
| setOutput('Sending request...'); |
| try { |
| const payload = { |
| user_id: userId.value, |
| text: textInput.value, |
| survey_answers: parseSurvey(), |
| locale: 'en', |
| client_ts: new Date().toISOString(), |
| }; |
| const res = await fetch(`${baseUrl.value}/v1/analysis`, { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify(payload), |
| }); |
| const json = await res.json(); |
| setOutput(json); |
| } catch (err) { |
| setOutput(err.message || String(err), true); |
| } |
| }); |
| |
| document.getElementById('historyBtn').addEventListener('click', async () => { |
| setOutput('Fetching history...'); |
| try { |
| const res = await fetch(`${baseUrl.value}/v1/users/${userId.value}/analyses?limit=20&offset=0`); |
| const json = await res.json(); |
| setOutput(json); |
| } catch (err) { |
| setOutput(err.message || String(err), true); |
| } |
| }); |
| </script> |
| </body> |
| </html> |
|
|