Szatuna/api/index.php
2026-02-26 14:35:27 +01:00

630 lines
14 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Dokumentáció</title>
<style>
:root {
--color-bg-primary: #f5f5f5;
--color-bg-secondary: #ffffff;
--color-text-primary: #1a1a1a;
--color-text-secondary: #666666;
--color-border: #e0e0e0;
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-success: #059669;
--color-warning: #d97706;
--color-error: #dc2626;
--color-code-bg: #f3f4f6;
--sidebar-width: 250px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
line-height: 1.6;
}
header {
background-color: var(--color-bg-secondary);
border-bottom: 1px solid var(--color-border);
padding: 20px 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.header-container {
max-width: 1400px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
font-size: 24px;
font-weight: 600;
margin-bottom: 5px;
}
.header-subtitle {
color: var(--color-text-secondary);
font-size: 14px;
}
.container {
max-width: 1400px;
margin: 0 auto;
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
gap: 0;
min-height: calc(100vh - 80px);
}
aside {
background-color: var(--color-bg-secondary);
border-right: 1px solid var(--color-border);
padding: 20px;
position: sticky;
top: 80px;
height: calc(100vh - 80px);
overflow-y: auto;
}
.nav-section {
margin-bottom: 25px;
}
.nav-section-title {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 10px;
letter-spacing: 0.5px;
}
.nav-link {
display: block;
padding: 8px 12px;
margin-bottom: 5px;
color: var(--color-text-secondary);
text-decoration: none;
border-radius: 4px;
transition: all 0.2s ease;
font-size: 14px;
}
.nav-link:hover {
background-color: var(--color-bg-primary);
color: var(--color-primary);
}
.nav-link.active {
background-color: rgba(37, 99, 235, 0.1);
color: var(--color-primary);
font-weight: 500;
}
main {
padding: 40px;
overflow-y: auto;
}
section {
margin-bottom: 50px;
scroll-margin-top: 100px;
}
section:first-child {
margin-top: 0;
}
h2 {
font-size: 28px;
font-weight: 600;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid var(--color-border);
}
h3 {
font-size: 18px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 12px;
color: var(--color-primary);
}
p {
margin-bottom: 12px;
color: var(--color-text-secondary);
}
.endpoint-block {
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 20px;
margin-bottom: 20px;
margin-top: 15px;
}
.endpoint-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.method-badge {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.method-get {
background-color: #dbeafe;
color: #1e40af;
}
.method-post {
background-color: #dcfce7;
color: #166534;
}
.method-put {
background-color: #fed7aa;
color: #92400e;
}
.method-delete {
background-color: #fee2e2;
color: #991b1b;
}
.endpoint-url {
font-family: 'Monaco', 'Menlo', monospace;
background-color: var(--color-code-bg);
padding: 8px 12px;
border-radius: 4px;
font-size: 13px;
word-break: break-all;
flex: 1;
min-width: 200px;
}
.description {
margin-bottom: 15px;
padding: 12px;
background-color: var(--color-bg-primary);
border-left: 3px solid var(--color-primary);
border-radius: 0 4px 4px 0;
}
.param-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
font-size: 14px;
}
.param-table th {
background-color: var(--color-code-bg);
padding: 12px;
text-align: left;
font-weight: 600;
border-bottom: 2px solid var(--color-border);
}
.param-table td {
padding: 10px 12px;
border-bottom: 1px solid var(--color-border);
}
.param-table tr:hover {
background-color: var(--color-bg-primary);
}
.param-name {
font-family: 'Monaco', 'Menlo', monospace;
font-weight: 600;
color: var(--color-primary);
}
.param-type {
background-color: var(--color-code-bg);
padding: 2px 6px;
border-radius: 3px;
font-family: 'Monaco', 'Menlo', monospace;
font-size: 12px;
color: var(--color-text-secondary);
}
.required {
background-color: #fee2e2;
color: #991b1b;
padding: 2px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 600;
}
.optional {
background-color: #fef3c7;
color: #92400e;
padding: 2px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 600;
}
.code-block {
background-color: #1f2937;
color: #e5e7eb;
padding: 15px;
border-radius: 6px;
overflow-x: auto;
margin: 15px 0;
font-family: 'Monaco', 'Menlo', monospace;
font-size: 13px;
line-height: 1.5;
}
.code-label {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 8px;
letter-spacing: 0.5px;
}
.response-example {
margin-top: 15px;
}
.status-code {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
font-weight: 600;
font-size: 13px;
margin-bottom: 8px;
font-family: 'Monaco', 'Menlo', monospace;
}
.status-200 {
background-color: #dcfce7;
color: #166534;
}
.status-400 {
background-color: #fecaca;
color: #7c2d12;
}
.status-401 {
background-color: #fecaca;
color: #7c2d12;
}
.status-404 {
background-color: #fecaca;
color: #7c2d12;
}
.status-500 {
background-color: #fee2e2;
color: #7f1d1d;
}
.key-value {
display: grid;
grid-template-columns: auto 1fr;
gap: 15px;
margin: 10px 0;
}
.key-value dt {
font-weight: 600;
color: var(--color-primary);
}
.key-value dd {
margin: 0;
color: var(--color-text-secondary);
}
.note-box {
background-color: #eff6ff;
border-left: 4px solid var(--color-primary);
padding: 15px;
border-radius: 4px;
margin: 15px 0;
}
.note-box strong {
color: var(--color-primary);
}
.error-codes {
margin-top: 20px;
}
.error-item {
display: grid;
grid-template-columns: 100px 1fr;
gap: 15px;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
.error-code {
font-family: 'Monaco', 'Menlo', monospace;
font-weight: 600;
color: var(--color-error);
}
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
aside {
display: none;
}
main {
padding: 20px;
}
h2 {
font-size: 22px;
}
.endpoint-header {
flex-direction: column;
align-items: flex-start;
}
.endpoint-url {
width: 100%;
}
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #999;
}
</style>
</head>
<body>
<header>
<div class="header-container">
<h1>API Dokumentáció</h1>
<p class="header-subtitle">Verzió 1.0.0 | Utolsó frissítés: 2025. december 29.</p>
</div>
</header>
<div class="container">
<aside>
<div class="nav-section">
<div class="nav-section-title">Bevezetés</div>
<a href="#overview" class="nav-link active">Áttekintés</a>
<a href="#authentication" class="nav-link">Hitelesítés</a>
</div>
<div class="nav-section">
<div class="nav-section-title">GET Végpontok</div>
<a href="#get-stock" class="nav-link">Raktárkészlet</a>
</div>
<div class="nav-section">
<div class="nav-section-title">Teknikai adatok</div>
<a href="#formats" class="nav-link">Válasz formátumok</a>
<a href="#error-codes" class="nav-link">Hibakódok</a>
</div>
</aside>
<main>
<!-- OVERVIEW -->
<section id="overview">
<h2>Áttekintés</h2>
<p>A Szaturnusz rendszerhez tartozó Web API-k leírását tekintheti meg.</p>
<div class="note-box">
<strong>Alap URL:</strong> https://zimbra.szatuna.hu:18821
</div>
</section>
<!-- AUTHENTICATION -->
<section id="authentication">
<h2>Hitelesítés</h2>
<p>Az API-k jelenleg nem igényelnek hitelesítést. Az összes végpont nyilvánosan elérhető.</p>
</section>
<!-- GET USERS -->
<section id="get-stock">
<h2>GET Végpontok</h2>
<h3>Teljes raktárkészlet lekérdezése</h3>
<div class="endpoint-block">
<div class="endpoint-header">
<span class="method-badge method-get">GET</span>
<span class="endpoint-url">/stock.php</span>
</div>
<div class="description">Az összes raktárban rendelkezésre álló cikkszám lekérdezése. Tartalmazza a szokványos raktárat, a fóliás raktárat és a szett cikkszámokat. Csak pozitív készletű cikkszámok kerülnek visszaadásra.</div>
<h4 style="margin-top: 20px; font-size: 14px; font-weight: 600;">Lekérdezési paraméterek</h4>
<table class="param-table">
<thead>
<tr>
<th>Paraméter</th>
<th>Típus</th>
<th>Státusz</th>
<th>Leírás</th>
</tr>
</thead>
<tbody>
<tr>
<td class="param-name">format</td>
<td><span class="param-type">string</span></td>
<td><span class="optional">opcionális</span></td>
<td>Válasz formátuma: json, csv, xml. Alapértelmezett: json</td>
</tr>
<tr>
<td class="param-name">item_id</td>
<td><span class="param-type">string</span></td>
<td><span class="optional">opcionális</span></td>
<td>Szűrés egy konkrét cikkszámra. Pontos egyezés szükséges</td>
</tr>
</tbody>
</table>
<div class="response-example">
<div class="code-label">Sikeres válasz (JSON)</div>
<span class="status-code status-200">200 OK</span>
<div class="code-block">[
{
"item_id": "PART001",
"total_amount": 42
},
{
"item_id": "PART002",
"total_amount": 15
},
{
"item_id": "PART003+PART004",
"total_amount": 8
}
]</div>
</div>
</div>
</section>
<!-- FORMATS -->
<section id="formats">
<h2>Válasz formátumok</h2>
<p>Az API-k támogatják a JSON, CSV és XML kimeneti formátumokat. Válassz a <code>format</code> paraméterrel.</p>
<h3>JSON formátum (alapértelmezett)</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=json</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">[
{
"item_id": "PART001",
"total_amount": 42
}
]</div>
</div>
<h3>CSV formátum</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=csv</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">item_id,total_amount
PART001,42
PART002,15
PART003+PART004,8</div>
</div>
<h3>XML formátum</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=xml</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">&lt;?xml version="1.0"?&gt;
&lt;root&gt;
&lt;item&gt;
&lt;item_id&gt;PART001&lt;/item_id&gt;
&lt;total_amount&gt;42&lt;/total_amount&gt;
&lt;/item&gt;
&lt;/root&gt;</div>
</div>
</section>
<!-- ERROR CODES -->
<section id="error-codes">
<h2>Hibák és státuszkódok</h2>
<p>Az API-k lekérdezési hibái közvetlenül a kimenetre íródnak. Az alábbi HTTP státuszkódok lehetségesek:</p>
<div class="error-codes">
<div class="error-item">
<div class="error-code">200 OK</div>
<div>A kérés sikeres. Az eredmények JSON/CSV/XML formátumban kerülnek visszaadásra</div>
</div>
<div class="error-item">
<div class="error-code">500 Internal Server Error</div>
<div>Adatbázis kapcsolat vagy lekérdezési hiba. Az error üzenet az stdout-ra íródik</div>
</div>
</div>
<h3>Paraméter validáció</h3>
<p>Az API alapértelmezés szerint figyelmen kívül hagyja az érvénytelen paramétereket:</p>
<ul style="margin-top: 12px; margin-left: 20px;">
<li><code>format</code> Érvénytelen érték esetén JSON alapértelmezett</li>
<li><code>item_id</code> Nem tárolt item_id esetén üres tömb kerül visszaadásra</li>
</ul>
</section>
</main>
</div>
<script type="text/javascript">
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('.nav-link');
window.addEventListener('scroll', () => {
let currentSection = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.clientHeight;
if (pageYOffset >= sectionTop - 200) {
currentSection = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${currentSection}`) {
link.classList.add('active');
}
});
});
</script>
</body>
</html>