From 9bf9d09f185d154f53c19f208008c4a80d38243e Mon Sep 17 00:00:00 2001 From: AugistineCreates Date: Tue, 2 Jun 2026 11:47:29 +0100 Subject: [PATCH 1/3] feat: skeleton and aria-live loading state for test call --- src/ApiUsage.tsx | 25 ++++++++++++++++++++++--- src/index.css | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/ApiUsage.tsx b/src/ApiUsage.tsx index adafb20..ea9733c 100644 --- a/src/ApiUsage.tsx +++ b/src/ApiUsage.tsx @@ -1,5 +1,7 @@ import { useState } from 'react'; import EmptyState from '../components/EmptyState'; +import Skeleton from './components/Skeleton'; + type ApiEndpoint = { id: string; @@ -368,19 +370,36 @@ export default function ApiUsage() { {(apiResponse || isLoading) && ( -
+

Response

{isLoading ? ( -
Loading...
+
+
+ + +
+
+ + + + + +
+
) : (
diff --git a/src/index.css b/src/index.css index e1cae39..c613f47 100644 --- a/src/index.css +++ b/src/index.css @@ -2561,3 +2561,37 @@ code, color: var(--text); cursor: pointer; } + +/* Button Spinner & Loading States */ +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.button-spinner { + display: inline-block; + width: 16px; + height: 16px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-top-color: #ffffff; + border-radius: 50%; + animation: spin 0.6s linear infinite; + margin-right: 8px; + flex-shrink: 0; +} + +.primary-button.button-loading { + cursor: not-allowed; +} + +/* Response JSON Skeleton Container */ +.response-json-skeleton { + background: var(--surface); + padding: 16px; + border-radius: 8px; + display: flex; + flex-direction: column; + gap: 12px; +} + From d4c1f22af415f80c87c955e77c094bbf10c645e2 Mon Sep 17 00:00:00 2001 From: AugistineCreates Date: Tue, 2 Jun 2026 11:50:13 +0100 Subject: [PATCH 2/3] fix: resolve out-of-order state variable declarations, correct import paths, and restore missing Dashboard import --- src/ApiUsage.tsx | 4 ++-- src/App.tsx | 1 + src/components/Dashboard.tsx | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ApiUsage.tsx b/src/ApiUsage.tsx index ea9733c..8944082 100644 --- a/src/ApiUsage.tsx +++ b/src/ApiUsage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import EmptyState from '../components/EmptyState'; +import EmptyState from './components/EmptyState'; import Skeleton from './components/Skeleton'; @@ -147,11 +147,11 @@ export default function ApiUsage() { const [apiResponse, setApiResponse] = useState(null); const [responseTime, setResponseTime] = useState(null); const [callCost, setCallCost] = useState(null); + const [statusFilter, setStatusFilter] = useState<'all' | 'success' | 'error'>('all'); const [callHistory, setCallHistory] = useState(MOCK_CALL_HISTORY); const filteredCallHistory = statusFilter === 'all' ? callHistory : callHistory.filter(call => call.status === statusFilter); const [selectedLanguage, setSelectedLanguage] = useState<'javascript' | 'python' | 'curl'>('javascript'); const [expandedCall, setExpandedCall] = useState(null); - const [statusFilter, setStatusFilter] = useState<'all' | 'success' | 'error'>('all'); const [usageStats, setUsageStats] = useState({ callsToday: 47, diff --git a/src/App.tsx b/src/App.tsx index 4ee2443..2e9d1d4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,7 @@ import { ThemeToggle } from './ThemeToggle'; import ApiUsage from './ApiUsage'; import ServerError from './components/ServerError'; import NotFound from './components/NotFound'; +import Dashboard from './components/Dashboard'; type DepositStage = 'input' | 'approving' | 'pending' | 'confirmed' | 'failed'; type DemoOutcome = 'confirmed' | 'failed'; diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index ef3a7be..2aa766c 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import './Dashboard.css'; import { useNavigate } from 'react-router-dom'; import Skeleton from '../components/Skeleton'; From c820be1f48c3c4ace0902c0dc599e2ccf0a61b02 Mon Sep 17 00:00:00 2001 From: AugistineCreates Date: Tue, 2 Jun 2026 11:57:37 +0100 Subject: [PATCH 3/3] task: color-blind-safe HTTP method badges --- src/index.css | 87 +++++++++++++++++++++++++++++++++++++ src/pages/ApiDetailPage.tsx | 10 +---- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/index.css b/src/index.css index c613f47..35e738f 100644 --- a/src/index.css +++ b/src/index.css @@ -31,6 +31,27 @@ rgba(20, 27, 50, 0.98), rgba(12, 18, 34, 0.98) ); + + /* HTTP Method Badge Tokens - Dark Theme (High Contrast / Accessible) */ + --method-get-bg: rgba(59, 130, 246, 0.16); + --method-get-color: #60a5fa; + --method-get-border: rgba(59, 130, 246, 0.35); + + --method-post-bg: rgba(16, 185, 129, 0.16); + --method-post-color: #34d399; + --method-post-border: rgba(16, 185, 129, 0.35); + + --method-put-bg: rgba(245, 158, 11, 0.16); + --method-put-color: #fbbf24; + --method-put-border: rgba(245, 158, 11, 0.35); + + --method-delete-bg: rgba(239, 68, 68, 0.16); + --method-delete-color: #f87171; + --method-delete-border: rgba(239, 68, 68, 0.35); + + --method-patch-bg: rgba(139, 92, 246, 0.16); + --method-patch-color: #a78bfa; + --method-patch-border: rgba(139, 92, 246, 0.35); } [data-theme="light"] { @@ -55,6 +76,27 @@ rgba(255, 255, 255, 0.98), rgba(248, 250, 255, 0.98) ); + + /* HTTP Method Badge Tokens - Light Theme (High Contrast / Accessible) */ + --method-get-bg: rgba(37, 99, 235, 0.1); + --method-get-color: #1e40af; + --method-get-border: rgba(37, 99, 235, 0.25); + + --method-post-bg: rgba(5, 150, 105, 0.1); + --method-post-color: #065f46; + --method-post-border: rgba(5, 150, 105, 0.25); + + --method-put-bg: rgba(217, 119, 6, 0.1); + --method-put-color: #92400e; + --method-put-border: rgba(217, 119, 6, 0.25); + + --method-delete-bg: rgba(220, 38, 38, 0.1); + --method-delete-color: #991b1b; + --method-delete-border: rgba(220, 38, 38, 0.25); + + --method-patch-bg: rgba(109, 40, 217, 0.1); + --method-patch-color: #5b21b6; + --method-patch-border: rgba(109, 40, 217, 0.25); } * { @@ -2595,3 +2637,48 @@ code, gap: 12px; } +/* Accessible HTTP Method Badges */ +.method-badge { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 4px 8px; + border-radius: 6px; + font-size: 0.72rem; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.05em; + border: 1px solid transparent; +} + +.method-badge--get { + background: var(--method-get-bg); + color: var(--method-get-color); + border-color: var(--method-get-border); +} + +.method-badge--post { + background: var(--method-post-bg); + color: var(--method-post-color); + border-color: var(--method-post-border); +} + +.method-badge--put { + background: var(--method-put-bg); + color: var(--method-put-color); + border-color: var(--method-put-border); +} + +.method-badge--patch { + background: var(--method-patch-bg); + color: var(--method-patch-color); + border-color: var(--method-patch-border); +} + +.method-badge--delete { + background: var(--method-delete-bg); + color: var(--method-delete-color); + border-color: var(--method-delete-border); +} + + diff --git a/src/pages/ApiDetailPage.tsx b/src/pages/ApiDetailPage.tsx index 415fcb4..e76e34c 100644 --- a/src/pages/ApiDetailPage.tsx +++ b/src/pages/ApiDetailPage.tsx @@ -549,15 +549,7 @@ print(data)`;
{ep.method}