diff --git a/src/i18n/locales/de/translation.json b/src/i18n/locales/de/translation.json index e05bc58d..424b336d 100644 --- a/src/i18n/locales/de/translation.json +++ b/src/i18n/locales/de/translation.json @@ -1008,6 +1008,92 @@ "issueResolved": "Problem gelöst" } }, + "apiDocsPage": { + "title": "Eryxon Flow API", + "description": "Produktions-Workflow-Management-API für Blechfertigung. Erstellen Sie Integrationen, automatisieren Sie Workflows und verwalten Sie Ihre Produktionsdaten programmgesteuert.", + "version": "v1.0.0", + "restApi": "REST API", + "restApiDesc": "JSON-basierte RESTful API", + "apiKeyAuth": "API-Schlüssel-Auth", + "apiKeyAuthDesc": "Sichere Bearer-Token-Authentifizierung", + "interactiveDocs": "Interaktive Dokumentation", + "interactiveDocsDesc": "Endpunkte direkt im Browser testen", + "openApiSpec": "OpenAPI-Spezifikation", + "openApiSpecDesc": "Laden Sie die Spezifikation herunter für Swagger, Postman oder zur SDK-Generierung", + "downloadJson": "JSON herunterladen", + "downloadJsonDesc": "OpenAPI 3.0 Spezifikation", + "downloadYaml": "YAML herunterladen", + "downloadYamlDesc": "Menschenlesbares Format", + "swaggerEditor": "Swagger Editor", + "swaggerEditorDesc": "Online bearbeiten & validieren", + "copySpecUrl": "Spec-URL kopieren", + "copySpecUrlDesc": "Direkter Link zum JSON", + "importToPostman": "In Postman importieren", + "importToPostmanDesc": "Postman öffnen → Import → Link → Einfügen:", + "copyUrl": "URL kopieren", + "csvImportWizard": "CSV-Import-Assistent", + "helpAndGuides": "Hilfe & Anleitungen", + "quickStart": "Schnellstart", + "codeExamples": "Code-Beispiele", + "tryItOut": "Ausprobieren", + "fullReference": "Vollständige Referenz", + "gettingStarted": "In 3 Schritten starten", + "gettingStartedDesc": "Starten Sie in wenigen Minuten mit API-Aufrufen", + "step1Title": "API-Schlüssel generieren", + "step1Desc": "Navigieren Sie zu Admin > API-Schlüssel in der Weboberfläche und generieren Sie einen neuen API-Schlüssel.", + "step1KeyPrefix": "Ihr Schlüssel beginnt mit", + "keepApiKeySecure": "Halten Sie Ihren API-Schlüssel sicher!", + "keepApiKeySecureDesc": "Ihr API-Schlüssel wird nur einmal angezeigt. Speichern Sie ihn sicher und committen Sie ihn niemals in die Versionskontrolle.", + "goToApiKeys": "Zu API-Schlüssel", + "step2Title": "Verbindung testen", + "step2Desc": "Führen Sie Ihren ersten API-Aufruf durch, um zu überprüfen, ob Ihr Schlüssel funktioniert. Wir empfehlen, mit dem schreibgeschützten Endpunkt zu beginnen", + "step2Endpoint": "/api-stages", + "step2EndpointDesc": "", + "baseUrl": "Basis-URL", + "curlExample": "cURL-Beispiel", + "expectedResponse": "Erwartete Antwort", + "step3Title": "Mit dem Entwickeln beginnen", + "step3Desc": "Erkunden Sie die API-Referenz unten, um alle verfügbaren Endpunkte zu sehen und sie interaktiv zu testen.", + "commonUseCases": "Häufige Anwendungsfälle", + "useCase1": "Aufträge aus ERP-Systemen erstellen", + "useCase2": "Produktionsfortschritt verfolgen", + "useCase3": "Aufgabenabschluss aktualisieren", + "useCase4": "Auftragsstatus und Metriken abfragen", + "bestPractices": "Best Practices", + "practice1": "Paginierung für große Datensätze verwenden", + "practice2": "Exponentiellen Backoff implementieren", + "practice3": "Rate-Limit-Header behandeln", + "practice4": "Antworten validieren", + "codeExamplesTitle": "Code-Beispiele", + "codeExamplesDesc": "Sofort einsetzbare Code-Snippets in mehreren Programmiersprachen", + "authentication": "Authentifizierung", + "authDesc": "Alle API-Anfragen erfordern Authentifizierung mit einem API-Schlüssel im Authorization-Header:", + "headerFormat": "Header-Format", + "rateLimiting": "Rate-Limiting", + "rateLimitingDesc": "API-Anfragen sind begrenzt. Prüfen Sie die X-RateLimit-* Header in den Antworten für aktuelle Limits und Nutzung.", + "interactiveTesting": "Interaktive API-Tests", + "interactiveTestingDesc": "Testen Sie API-Endpunkte direkt in Ihrem Browser. Keine zusätzlichen Tools erforderlich!", + "howToTest": "So testen Sie", + "howToTestStep1": "Klicken Sie auf die Schaltfläche \"Autorisieren\" unten (grünes Schloss-Symbol)", + "howToTestStep2": "Geben Sie Ihren API-Schlüssel ein:", + "howToTestStep3": "Erweitern Sie einen Endpunkt und klicken Sie auf \"Ausprobieren\"", + "howToTestStep4": "Füllen Sie die Parameter aus und klicken Sie auf \"Ausführen\"", + "quickTestEndpoints": "Schnelltest-Endpunkte", + "stagesEndpointDesc": "Bester Endpunkt zum Testen Ihres API-Schlüssels. Gibt alle Produktionsstufen zurück.", + "jobsGetEndpointDesc": "Alle Aufträge mit Filterung auflisten. Paginierung mit limit/offset testen.", + "jobsPostEndpointDesc": "Einen neuen Auftrag erstellen. Enthält Beispiel-Request-Body.", + "jobsSyncEndpointDesc": "ERP-Sync-Endpunkt. Upsert nach external_id.", + "completeApiReference": "Vollständige API-Referenz", + "completeApiReferenceDesc": "Vollständige OpenAPI-Spezifikation mit allen Endpunkten, Schemas und Beispielen.", + "openInSwaggerEditor": "In Swagger Editor öffnen", + "downloaded": "Heruntergeladen!", + "downloadedDesc": "OpenAPI-Spezifikation als {{filename}} heruntergeladen", + "downloadError": "Spezifikation konnte nicht heruntergeladen werden", + "copied": "Kopiert!", + "copiedDesc": "{{label}} in Zwischenablage kopiert", + "specUrl": "Spec-URL", + "postmanImportUrl": "Postman-Import-URL" + }, "dataExport": { "title": "Datenexport", "chooseEntities": "Entitäten auswählen", diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index cb61ea06..6bd85dd8 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -1140,9 +1140,99 @@ "issueResolved": "Issue Resolved" } }, + "apiDocsPage": { + "title": "Eryxon Flow API", + "description": "Production workflow management API for sheet metal manufacturing. Build integrations, automate workflows, and manage your production data programmatically.", + "version": "v1.0.0", + "restApi": "REST API", + "restApiDesc": "JSON-based RESTful API", + "apiKeyAuth": "API Key Auth", + "apiKeyAuthDesc": "Secure bearer token authentication", + "interactiveDocs": "Interactive Docs", + "interactiveDocsDesc": "Test endpoints directly in browser", + "openApiSpec": "OpenAPI Specification", + "openApiSpecDesc": "Download the spec to use with Swagger, Postman, or generate client SDKs", + "downloadJson": "Download JSON", + "downloadJsonDesc": "OpenAPI 3.0 spec", + "downloadYaml": "Download YAML", + "downloadYamlDesc": "Human-readable format", + "swaggerEditor": "Swagger Editor", + "swaggerEditorDesc": "Edit & validate online", + "copySpecUrl": "Copy Spec URL", + "copySpecUrlDesc": "Direct link to JSON", + "importToPostman": "Import to Postman", + "importToPostmanDesc": "Open Postman → Import → Link → Paste:", + "copyUrl": "Copy URL", + "csvImportWizard": "CSV Import Wizard", + "helpAndGuides": "Help & Guides", + "quickStart": "Quick Start", + "codeExamples": "Code Examples", + "tryItOut": "Try It Out", + "fullReference": "Full Reference", + "gettingStarted": "Getting Started in 3 Steps", + "gettingStartedDesc": "Start making API calls in minutes with this beginner-friendly guide", + "step1Title": "Generate an API Key", + "step1Desc": "Navigate to Admin > API Keys in the web interface and generate a new API key.", + "step1KeyPrefix": "Your key will start with", + "keepApiKeySecure": "Keep your API key secure!", + "keepApiKeySecureDesc": "Your API key is shown only once. Store it securely and never commit it to version control.", + "goToApiKeys": "Go to API Keys", + "step2Title": "Test Your Connection", + "step2Desc": "Make your first API call to verify your key works. We recommend starting with the read-only", + "step2Endpoint": "/api-stages", + "step2EndpointDesc": "endpoint.", + "baseUrl": "Base URL", + "curlExample": "cURL Example", + "expectedResponse": "Expected Response", + "step3Title": "Start Building", + "step3Desc": "Explore the API Reference below to see all available endpoints and try them interactively.", + "commonUseCases": "Common Use Cases", + "useCase1": "Create jobs from ERP systems", + "useCase2": "Track production progress", + "useCase3": "Update task completion", + "useCase4": "Query job status and metrics", + "bestPractices": "Best Practices", + "practice1": "Use pagination for large datasets", + "practice2": "Implement exponential backoff", + "practice3": "Handle rate limit headers", + "practice4": "Validate responses", + "codeExamplesTitle": "Code Examples", + "codeExamplesDesc": "Ready-to-use code snippets in multiple programming languages", + "authentication": "Authentication", + "authDesc": "All API requests require authentication using an API key in the Authorization header:", + "headerFormat": "Header Format", + "rateLimiting": "Rate Limiting", + "rateLimitingDesc": "API requests are rate-limited. Check the X-RateLimit-* headers in responses for current limits and usage.", + "interactiveTesting": "Interactive API Testing", + "interactiveTestingDesc": "Test API endpoints directly in your browser. No additional tools required!", + "howToTest": "How to Test", + "howToTestStep1": "Click the \"Authorize\" button below (green lock icon)", + "howToTestStep2": "Enter your API key:", + "howToTestStep3": "Expand any endpoint and click \"Try it out\"", + "howToTestStep4": "Fill in parameters and click \"Execute\"", + "quickTestEndpoints": "Quick Test Endpoints", + "stagesEndpointDesc": "Best endpoint to test your API key. Returns all production stages.", + "jobsGetEndpointDesc": "List all jobs with filtering. Test pagination with limit/offset.", + "jobsPostEndpointDesc": "Create a new job. Includes example request body.", + "jobsSyncEndpointDesc": "ERP sync endpoint. Upsert by external_id.", + "completeApiReference": "Complete API Reference", + "completeApiReferenceDesc": "Full OpenAPI specification with all endpoints, schemas, and examples.", + "openInSwaggerEditor": "Open in Swagger Editor", + "downloaded": "Downloaded!", + "downloadedDesc": "OpenAPI spec downloaded as {{filename}}", + "downloadError": "Failed to download spec", + "copied": "Copied!", + "copiedDesc": "{{label}} copied to clipboard", + "specUrl": "Spec URL", + "postmanImportUrl": "Postman import URL" + }, "dataImport": { "title": "Data Import", "description": "Import data from CSV files or external systems", + "needHelp": "Need Help?", + "learnMoreSync": "Learn more about data sync options:", + "erpIntegrationGuide": "ERP Integration Guide", + "apiDocumentation": "API Documentation", "steps": { "select": "Select Entity", "upload": "Upload File", diff --git a/src/i18n/locales/nl/translation.json b/src/i18n/locales/nl/translation.json index 3385ee50..03f45b2a 100644 --- a/src/i18n/locales/nl/translation.json +++ b/src/i18n/locales/nl/translation.json @@ -1278,6 +1278,92 @@ "issueResolved": "Probleem opgelost" } }, + "apiDocsPage": { + "title": "Eryxon Flow API", + "description": "Productie workflow management API voor plaatwerk fabricage. Bouw integraties, automatiseer workflows en beheer uw productiegegevens programmatisch.", + "version": "v1.0.0", + "restApi": "REST API", + "restApiDesc": "JSON-gebaseerde RESTful API", + "apiKeyAuth": "API-sleutel authenticatie", + "apiKeyAuthDesc": "Veilige bearer token authenticatie", + "interactiveDocs": "Interactieve documentatie", + "interactiveDocsDesc": "Test endpoints direct in de browser", + "openApiSpec": "OpenAPI-specificatie", + "openApiSpecDesc": "Download de specificatie voor Swagger, Postman of SDK-generatie", + "downloadJson": "JSON downloaden", + "downloadJsonDesc": "OpenAPI 3.0 specificatie", + "downloadYaml": "YAML downloaden", + "downloadYamlDesc": "Menselijk leesbaar formaat", + "swaggerEditor": "Swagger Editor", + "swaggerEditorDesc": "Online bewerken & valideren", + "copySpecUrl": "Spec-URL kopiëren", + "copySpecUrlDesc": "Directe link naar JSON", + "importToPostman": "Importeren in Postman", + "importToPostmanDesc": "Postman openen → Import → Link → Plakken:", + "copyUrl": "URL kopiëren", + "csvImportWizard": "CSV Import Wizard", + "helpAndGuides": "Help & handleidingen", + "quickStart": "Snelstart", + "codeExamples": "Codevoorbeelden", + "tryItOut": "Uitproberen", + "fullReference": "Volledige referentie", + "gettingStarted": "In 3 stappen aan de slag", + "gettingStartedDesc": "Begin binnen enkele minuten met API-aanroepen", + "step1Title": "API-sleutel genereren", + "step1Desc": "Navigeer naar Admin > API-sleutels in de webinterface en genereer een nieuwe API-sleutel.", + "step1KeyPrefix": "Uw sleutel begint met", + "keepApiKeySecure": "Houd uw API-sleutel veilig!", + "keepApiKeySecureDesc": "Uw API-sleutel wordt slechts één keer getoond. Bewaar deze veilig en commit deze nooit naar versiebeheer.", + "goToApiKeys": "Naar API-sleutels", + "step2Title": "Verbinding testen", + "step2Desc": "Maak uw eerste API-aanroep om te verifiëren dat uw sleutel werkt. We raden aan te beginnen met het alleen-lezen endpoint", + "step2Endpoint": "/api-stages", + "step2EndpointDesc": "", + "baseUrl": "Basis-URL", + "curlExample": "cURL-voorbeeld", + "expectedResponse": "Verwachte respons", + "step3Title": "Begin met bouwen", + "step3Desc": "Verken de API-referentie hieronder om alle beschikbare endpoints te zien en ze interactief te testen.", + "commonUseCases": "Veelvoorkomende use cases", + "useCase1": "Opdrachten maken vanuit ERP-systemen", + "useCase2": "Productievoortgang volgen", + "useCase3": "Taakafronding bijwerken", + "useCase4": "Opdrachtstatus en metrics opvragen", + "bestPractices": "Best practices", + "practice1": "Paginering gebruiken voor grote datasets", + "practice2": "Exponentiële backoff implementeren", + "practice3": "Rate limit headers afhandelen", + "practice4": "Responses valideren", + "codeExamplesTitle": "Codevoorbeelden", + "codeExamplesDesc": "Kant-en-klare code snippets in meerdere programmeertalen", + "authentication": "Authenticatie", + "authDesc": "Alle API-verzoeken vereisen authenticatie met een API-sleutel in de Authorization header:", + "headerFormat": "Header-formaat", + "rateLimiting": "Rate limiting", + "rateLimitingDesc": "API-verzoeken zijn gelimiteerd. Controleer de X-RateLimit-* headers in responses voor huidige limieten en gebruik.", + "interactiveTesting": "Interactief API testen", + "interactiveTestingDesc": "Test API-endpoints direct in uw browser. Geen extra tools nodig!", + "howToTest": "Hoe te testen", + "howToTestStep1": "Klik op de \"Autoriseren\" knop hieronder (groen slot-icoon)", + "howToTestStep2": "Voer uw API-sleutel in:", + "howToTestStep3": "Vouw een endpoint uit en klik op \"Probeer het uit\"", + "howToTestStep4": "Vul de parameters in en klik op \"Uitvoeren\"", + "quickTestEndpoints": "Sneltest-endpoints", + "stagesEndpointDesc": "Beste endpoint om uw API-sleutel te testen. Retourneert alle productiefasen.", + "jobsGetEndpointDesc": "Lijst alle opdrachten met filtering. Test paginering met limit/offset.", + "jobsPostEndpointDesc": "Maak een nieuwe opdracht. Bevat voorbeeld request body.", + "jobsSyncEndpointDesc": "ERP sync endpoint. Upsert op external_id.", + "completeApiReference": "Volledige API-referentie", + "completeApiReferenceDesc": "Volledige OpenAPI-specificatie met alle endpoints, schema's en voorbeelden.", + "openInSwaggerEditor": "Openen in Swagger Editor", + "downloaded": "Gedownload!", + "downloadedDesc": "OpenAPI-specificatie gedownload als {{filename}}", + "downloadError": "Specificatie kon niet worden gedownload", + "copied": "Gekopieerd!", + "copiedDesc": "{{label}} naar klembord gekopieerd", + "specUrl": "Spec-URL", + "postmanImportUrl": "Postman import URL" + }, "dataExport": { "title": "Gegevensexport", "chooseEntities": "Kies entiteiten", diff --git a/src/pages/ApiDocs.tsx b/src/pages/ApiDocs.tsx index 669dde82..bb75ca3b 100644 --- a/src/pages/ApiDocs.tsx +++ b/src/pages/ApiDocs.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; import SwaggerUI from "swagger-ui-react"; import "swagger-ui-react/swagger-ui.css"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; @@ -18,7 +19,13 @@ import { Terminal, Zap, FileJson, - PlayCircle + PlayCircle, + Download, + FileCode, + Link as LinkIcon, + Package, + FileUp, + HelpCircle } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; @@ -36,6 +43,102 @@ export default function ApiDocs() { }); }; + const downloadSpec = async (format: 'json' | 'yaml') => { + try { + const response = await fetch('/openapi.json'); + const spec = await response.json(); + + let content: string; + let filename: string; + let mimeType: string; + + if (format === 'json') { + content = JSON.stringify(spec, null, 2); + filename = 'eryxon-flow-openapi.json'; + mimeType = 'application/json'; + } else { + // Convert JSON to YAML (simple conversion) + content = jsonToYaml(spec); + filename = 'eryxon-flow-openapi.yaml'; + mimeType = 'application/x-yaml'; + } + + const blob = new Blob([content], { type: mimeType }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + + toast({ + title: "Downloaded!", + description: `OpenAPI spec downloaded as ${filename}`, + }); + } catch (error) { + toast({ + title: "Error", + description: "Failed to download spec", + variant: "destructive", + }); + } + }; + + // Simple JSON to YAML converter (handles common cases) + const jsonToYaml = (obj: any, indent = 0): string => { + const spaces = ' '.repeat(indent); + let result = ''; + + if (Array.isArray(obj)) { + for (const item of obj) { + if (typeof item === 'object' && item !== null) { + result += `${spaces}-\n${jsonToYaml(item, indent + 1).replace(/^ /, '')}`; + } else { + result += `${spaces}- ${formatYamlValue(item)}\n`; + } + } + } else if (typeof obj === 'object' && obj !== null) { + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'object' && value !== null) { + if (Array.isArray(value) && value.length === 0) { + result += `${spaces}${key}: []\n`; + } else if (typeof value === 'object' && Object.keys(value).length === 0) { + result += `${spaces}${key}: {}\n`; + } else { + result += `${spaces}${key}:\n${jsonToYaml(value, indent + 1)}`; + } + } else { + result += `${spaces}${key}: ${formatYamlValue(value)}\n`; + } + } + } + + return result; + }; + + const formatYamlValue = (value: any): string => { + if (value === null) return 'null'; + if (value === undefined) return ''; + if (typeof value === 'boolean') return value ? 'true' : 'false'; + if (typeof value === 'number') return String(value); + if (typeof value === 'string') { + if (value.includes('\n') || value.includes(':') || value.includes('#') || + value.includes('"') || value.includes("'") || value.startsWith(' ') || + value.endsWith(' ') || /^[\d.]+$/.test(value) || value === '') { + return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`; + } + return value; + } + return String(value); + }; + + const openInSwaggerEditor = () => { + const specUrl = encodeURIComponent(`${window.location.origin}/openapi.json`); + window.open(`https://editor.swagger.io/?url=${specUrl}`, '_blank'); + }; + const codeExamples = { curl: `# Test your API connection curl ${apiBaseUrl}/api-stages \\ @@ -231,8 +334,114 @@ apiClient.post('/api-jobs', jobData) + {/* Download & Tools Section */} + + + + + OpenAPI Specification + + + Download the spec to use with Swagger, Postman, or generate client SDKs + + + +
+ {/* Download JSON */} + + + {/* Download YAML */} + + + {/* Open in Swagger Editor */} + + + {/* Copy Spec URL */} + +
+ + {/* Postman Import Instructions */} +
+
+ +
+
Import to Postman
+
+ Open Postman → Import → Link → Paste: {window.location.origin}/openapi.json +
+ +
+
+
+ + {/* Related Resources */} +
+ + + + + + +
+
+
+ - + Quick Start @@ -241,9 +450,13 @@ apiClient.post('/api-jobs', jobData) Code Examples + + + Try It Out + - API Reference + Full Reference @@ -479,28 +692,121 @@ apiClient.post('/api-jobs', jobData) - {/* API Reference Tab */} + {/* Try It Out Tab - Interactive Testing */} + + + + + + Interactive API Testing + + + Test API endpoints directly in your browser. No additional tools required! + + + + + + How to Test + +
    +
  1. Click the "Authorize" button below (green lock icon)
  2. +
  3. Enter your API key: ery_live_xxxxx
  4. +
  5. Expand any endpoint and click "Try it out"
  6. +
  7. Fill in parameters and click "Execute"
  8. +
+
+
+ + {/* Quick Test Endpoints */} +
+ +
+ GET + /api-stages +
+

Best endpoint to test your API key. Returns all production stages.

+
+ +
+ GET + /api-jobs +
+

List all jobs with filtering. Test pagination with limit/offset.

+
+ +
+ POST + /api-jobs +
+

Create a new job. Includes example request body.

+
+ +
+ PUT + /api-jobs/sync +
+

ERP sync endpoint. Upsert by external_id.

+
+
+ + + +
+ +
+
+
+
+ + {/* API Reference Tab - Full Spec */} - Interactive API Reference + Complete API Reference - Explore all endpoints and test them directly in your browser. - Click "Authorize" and enter your API key to start testing. + Full OpenAPI specification with all endpoints, schemas, and examples. - - - Try it out! - - Click "Authorize" in the panel below, enter your API key (with the ery_live_ or ery_test_ prefix), - then click any endpoint to test it directly. - - +
+ + + +
+ {/* Quick Links Banner */} + + + Need Help? + + Learn more about data sync options: + + + + + + + + + {/* Progress Steps */}
{['select', 'upload', 'map', 'preview', 'import', 'complete'].map((step, index) => ( diff --git a/src/pages/common/ApiDocs.tsx b/src/pages/common/ApiDocs.tsx index 669dde82..bb75ca3b 100644 --- a/src/pages/common/ApiDocs.tsx +++ b/src/pages/common/ApiDocs.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; import SwaggerUI from "swagger-ui-react"; import "swagger-ui-react/swagger-ui.css"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; @@ -18,7 +19,13 @@ import { Terminal, Zap, FileJson, - PlayCircle + PlayCircle, + Download, + FileCode, + Link as LinkIcon, + Package, + FileUp, + HelpCircle } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; @@ -36,6 +43,102 @@ export default function ApiDocs() { }); }; + const downloadSpec = async (format: 'json' | 'yaml') => { + try { + const response = await fetch('/openapi.json'); + const spec = await response.json(); + + let content: string; + let filename: string; + let mimeType: string; + + if (format === 'json') { + content = JSON.stringify(spec, null, 2); + filename = 'eryxon-flow-openapi.json'; + mimeType = 'application/json'; + } else { + // Convert JSON to YAML (simple conversion) + content = jsonToYaml(spec); + filename = 'eryxon-flow-openapi.yaml'; + mimeType = 'application/x-yaml'; + } + + const blob = new Blob([content], { type: mimeType }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + + toast({ + title: "Downloaded!", + description: `OpenAPI spec downloaded as ${filename}`, + }); + } catch (error) { + toast({ + title: "Error", + description: "Failed to download spec", + variant: "destructive", + }); + } + }; + + // Simple JSON to YAML converter (handles common cases) + const jsonToYaml = (obj: any, indent = 0): string => { + const spaces = ' '.repeat(indent); + let result = ''; + + if (Array.isArray(obj)) { + for (const item of obj) { + if (typeof item === 'object' && item !== null) { + result += `${spaces}-\n${jsonToYaml(item, indent + 1).replace(/^ /, '')}`; + } else { + result += `${spaces}- ${formatYamlValue(item)}\n`; + } + } + } else if (typeof obj === 'object' && obj !== null) { + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'object' && value !== null) { + if (Array.isArray(value) && value.length === 0) { + result += `${spaces}${key}: []\n`; + } else if (typeof value === 'object' && Object.keys(value).length === 0) { + result += `${spaces}${key}: {}\n`; + } else { + result += `${spaces}${key}:\n${jsonToYaml(value, indent + 1)}`; + } + } else { + result += `${spaces}${key}: ${formatYamlValue(value)}\n`; + } + } + } + + return result; + }; + + const formatYamlValue = (value: any): string => { + if (value === null) return 'null'; + if (value === undefined) return ''; + if (typeof value === 'boolean') return value ? 'true' : 'false'; + if (typeof value === 'number') return String(value); + if (typeof value === 'string') { + if (value.includes('\n') || value.includes(':') || value.includes('#') || + value.includes('"') || value.includes("'") || value.startsWith(' ') || + value.endsWith(' ') || /^[\d.]+$/.test(value) || value === '') { + return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`; + } + return value; + } + return String(value); + }; + + const openInSwaggerEditor = () => { + const specUrl = encodeURIComponent(`${window.location.origin}/openapi.json`); + window.open(`https://editor.swagger.io/?url=${specUrl}`, '_blank'); + }; + const codeExamples = { curl: `# Test your API connection curl ${apiBaseUrl}/api-stages \\ @@ -231,8 +334,114 @@ apiClient.post('/api-jobs', jobData) + {/* Download & Tools Section */} + + + + + OpenAPI Specification + + + Download the spec to use with Swagger, Postman, or generate client SDKs + + + +
+ {/* Download JSON */} + + + {/* Download YAML */} + + + {/* Open in Swagger Editor */} + + + {/* Copy Spec URL */} + +
+ + {/* Postman Import Instructions */} +
+
+ +
+
Import to Postman
+
+ Open Postman → Import → Link → Paste: {window.location.origin}/openapi.json +
+ +
+
+
+ + {/* Related Resources */} +
+ + + + + + +
+
+
+ - + Quick Start @@ -241,9 +450,13 @@ apiClient.post('/api-jobs', jobData) Code Examples + + + Try It Out + - API Reference + Full Reference @@ -479,28 +692,121 @@ apiClient.post('/api-jobs', jobData) - {/* API Reference Tab */} + {/* Try It Out Tab - Interactive Testing */} + + + + + + Interactive API Testing + + + Test API endpoints directly in your browser. No additional tools required! + + + + + + How to Test + +
    +
  1. Click the "Authorize" button below (green lock icon)
  2. +
  3. Enter your API key: ery_live_xxxxx
  4. +
  5. Expand any endpoint and click "Try it out"
  6. +
  7. Fill in parameters and click "Execute"
  8. +
+
+
+ + {/* Quick Test Endpoints */} +
+ +
+ GET + /api-stages +
+

Best endpoint to test your API key. Returns all production stages.

+
+ +
+ GET + /api-jobs +
+

List all jobs with filtering. Test pagination with limit/offset.

+
+ +
+ POST + /api-jobs +
+

Create a new job. Includes example request body.

+
+ +
+ PUT + /api-jobs/sync +
+

ERP sync endpoint. Upsert by external_id.

+
+
+ + + +
+ +
+
+
+
+ + {/* API Reference Tab - Full Spec */} - Interactive API Reference + Complete API Reference - Explore all endpoints and test them directly in your browser. - Click "Authorize" and enter your API key to start testing. + Full OpenAPI specification with all endpoints, schemas, and examples. - - - Try it out! - - Click "Authorize" in the panel below, enter your API key (with the ery_live_ or ery_test_ prefix), - then click any endpoint to test it directly. - - +
+ + + +