Răsfoiți Sursa

feat(api-docs): replace swagger-ui with scalar api reference

Replaced the static Swagger UI React component with dynamic Scalar API Reference
for improved API documentation experience. The new implementation loads the
Scalar reference dynamically via CDN and supports auto-generated OpenAPI
specification from `/api/openapi.json`.

- Removed swagger-ui-react and swagger-jsdoc dependencies
- Added @scalar/api-reference-react and @scalar/nextjs-api-reference packages
- Updated Next.js to latest version (15.4.1)
- Simplified API docs page with dynamic script loading
- Enhanced UI with modern Scalar design system
vidane 6 luni în urmă
părinte
comite
b5c7126a95
3 a modificat fișierele cu 633 adăugiri și 370 ștergeri
  1. 24 221
      app/api-docs/page.tsx
  2. 605 144
      package-lock.json
  3. 4 5
      package.json

+ 24 - 221
app/api-docs/page.tsx

@@ -1,227 +1,25 @@
 'use client';
 
-import SwaggerUI from 'swagger-ui-react';
-import 'swagger-ui-react/swagger-ui.css';
+import { useEffect } from 'react';
 
 export default function ApiDocs() {
-  const spec = {
-    openapi: '3.0.0',
-    info: {
-      title: 'Vtorio API',
-      version: '1.0.0',
-      description: 'File upload and management API for Vtorio application',
-    },
-    servers: [
-      {
-        url: process.env.NODE_ENV === 'production' 
-          ? 'https://your-domain.com' 
-          : 'http://localhost:3000',
-        description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server',
-      },
-    ],
-    paths: {
-      '/api/upload': {
-        post: {
-          summary: 'Upload a file',
-          description: 'Upload a file to the server and store it in the database',
-          tags: ['Files'],
-          requestBody: {
-            required: true,
-            content: {
-              'multipart/form-data': {
-                schema: {
-                  type: 'object',
-                  properties: {
-                    file: {
-                      type: 'string',
-                      format: 'binary',
-                      description: 'The file to upload',
-                    },
-                  },
-                  required: ['file'],
-                },
-              },
-            },
-          },
-          responses: {
-            '200': {
-              description: 'File uploaded successfully',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: true },
-                      file: {
-                        type: 'object',
-                        properties: {
-                          id: { type: 'string', example: 'clh123abc456' },
-                          filename: { type: 'string', example: 'document.pdf' },
-                          mimetype: { type: 'string', example: 'application/pdf' },
-                          size: { type: 'number', example: 1024000 },
-                          createdAt: { type: 'string', format: 'date-time' },
-                        },
-                      },
-                    },
-                  },
-                },
-              },
-            },
-            '400': {
-              description: 'Bad request - No file provided',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'No file provided' },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'Failed to upload file' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-      '/api/files': {
-        get: {
-          summary: 'List all files',
-          description: 'Get a list of all uploaded files with metadata',
-          tags: ['Files'],
-          responses: {
-            '200': {
-              description: 'List of files retrieved successfully',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: true },
-                      files: {
-                        type: 'array',
-                        items: {
-                          type: 'object',
-                          properties: {
-                            id: { type: 'string', example: 'clh123abc456' },
-                            filename: { type: 'string', example: 'document.pdf' },
-                            mimetype: { type: 'string', example: 'application/pdf' },
-                            size: { type: 'number', example: 1024000 },
-                            createdAt: { type: 'string', format: 'date-time' },
-                            updatedAt: { type: 'string', format: 'date-time' },
-                          },
-                        },
-                      },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'Failed to list files' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-      '/api/files/{id}': {
-        get: {
-          summary: 'Download a file',
-          description: 'Download a specific file by its ID',
-          tags: ['Files'],
-          parameters: [
-            {
-              name: 'id',
-              in: 'path',
-              required: true,
-              description: 'The ID of the file to download',
-              schema: {
-                type: 'string',
-                example: 'clh123abc456',
-              },
-            },
-          ],
-          responses: {
-            '200': {
-              description: 'File downloaded successfully',
-              content: {
-                'application/octet-stream': {
-                  schema: {
-                    type: 'string',
-                    format: 'binary',
-                  },
-                },
-              },
-              headers: {
-                'Content-Type': {
-                  description: 'MIME type of the file',
-                  schema: { type: 'string' },
-                },
-                'Content-Disposition': {
-                  description: 'Attachment header with filename',
-                  schema: { type: 'string' },
-                },
-                'Content-Length': {
-                  description: 'Size of the file in bytes',
-                  schema: { type: 'integer' },
-                },
-              },
-            },
-            '404': {
-              description: 'File not found',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      error: { type: 'string', example: 'File not found' },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      error: { type: 'string', example: 'Failed to retrieve file' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-    },
-  };
+  useEffect(() => {
+    // Load Scalar API Reference dynamically
+    const script = document.createElement('script');
+    script.src = 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/standalone.js';
+    script.async = true;
+    document.body.appendChild(script);
+
+    const style = document.createElement('link');
+    style.rel = 'stylesheet';
+    style.href = 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/style.css';
+    document.head.appendChild(style);
+
+    return () => {
+      document.body.removeChild(script);
+      document.head.removeChild(style);
+    };
+  }, []);
 
   return (
     <div className="min-h-screen bg-gray-50">
@@ -234,7 +32,12 @@ export default function ApiDocs() {
             <p className="text-gray-600 mb-6">
               Interactive API documentation for file upload and management endpoints.
             </p>
-            <SwaggerUI spec={spec} />
+            <div 
+              id="api-reference"
+              data-url="/api/openapi.json"
+              data-theme="default"
+              style={{ height: 'calc(100vh - 200px)' }}
+            />
           </div>
         </div>
       </div>

Fișier diff suprimat deoarece este prea mare
+ 605 - 144
package-lock.json


+ 4 - 5
package.json

@@ -10,14 +10,13 @@
   },
   "dependencies": {
     "@prisma/client": "^6.11.1",
-    "@types/swagger-ui-react": "^5.18.0",
-    "next": "15.1.6",
+    "@scalar/api-reference-react": "^0.7.33",
+    "@scalar/nextjs-api-reference": "^0.8.12",
+    "next": "^15.4.1",
     "pg": "^8.16.3",
     "prisma": "^6.11.1",
     "react": "^19.0.0",
-    "react-dom": "^19.0.0",
-    "swagger-jsdoc": "^6.2.8",
-    "swagger-ui-react": "^5.26.2"
+    "react-dom": "^19.0.0"
   },
   "devDependencies": {
     "@eslint/eslintrc": "^3",

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff