diff --git a/src/app/dashboard/docs/page.tsx b/src/app/dashboard/docs/page.tsx index 2568c78..8fa94b5 100644 --- a/src/app/dashboard/docs/page.tsx +++ b/src/app/dashboard/docs/page.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import React from 'react'; @@ -6,16 +5,52 @@ import DashboardLayout from '@/app/components/layout/DashboardLayout'; import Card from '@/app/components/ui/Card'; import { Tab } from '@headlessui/react'; import { CodeBracketIcon, ChatBubbleLeftIcon, PhotoIcon, UserIcon } from '@heroicons/react/24/outline'; -/* eslint-disable @typescript-eslint/ban-ts-comment */ -// @ts-ignore import SyntaxHighlighter from 'react-syntax-highlighter'; -/* eslint-enable @typescript-eslint/ban-ts-comment */ +import { useTheme } from '@/app/providers/ThemeProvider'; function classNames(...classes: string[]) { return classes.filter(Boolean).join(' '); } export default function DocsPage() { + const { theme } = useTheme(); + + // Custom purple Matrix-style theme + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const purpleMatrixTheme: any = { + 'hljs': { + display: 'block', + overflowX: 'auto', + padding: '1rem', + background: theme === 'dark' ? '#0a0a0a' : '#f8f8ff', + color: '#9d4edd', + borderRadius: '0.5rem' + }, + 'hljs-keyword': { color: '#c77dff' }, + 'hljs-string': { color: '#e0aaff' }, + 'hljs-number': { color: '#7b2cbf' }, + 'hljs-comment': { color: '#6c63ff', fontStyle: 'italic' }, + 'hljs-function': { color: '#8b5cf6' }, + 'hljs-variable': { color: '#a855f7' }, + 'hljs-property': { color: '#9333ea' }, + 'hljs-built_in': { color: '#7c3aed' }, + 'hljs-title': { color: '#6d28d9' }, + 'hljs-literal': { color: '#8b5cf6' }, + 'hljs-type': { color: '#7c3aed' }, + 'hljs-attribute': { color: '#9333ea' }, + 'hljs-meta': { color: '#6c63ff' }, + 'hljs-tag': { color: '#8b5cf6' }, + 'hljs-name': { color: '#a855f7' }, + 'hljs-attr': { color: '#9333ea' }, + 'hljs-selector-id': { color: '#7c3aed' }, + 'hljs-selector-class': { color: '#8b5cf6' }, + 'hljs-regexp': { color: '#c77dff' }, + 'hljs-link': { color: '#e0aaff' }, + 'hljs-symbol': { color: '#7b2cbf' }, + 'hljs-bullet': { color: '#9d4edd' }, + 'hljs-addition': { color: '#8b5cf6', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' }, + 'hljs-deletion': { color: '#7b2cbf', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' } + }; const tabs = [ { name: 'Overview', @@ -35,7 +70,7 @@ export default function DocsPage() { The API uses bearer token authentication. Include your API key in the Authorization header of your requests:

- + {`curl https://api.serika.dev/api/openai/v1/chat/completions \\ -H "Authorization: Bearer sk-your-api-key" \\ -H "Content-Type: application/json"`} @@ -73,7 +108,7 @@ export default function DocsPage() {

Error Handling

The API returns standard HTTP status codes and JSON error responses:

- + {`{ "error": { "message": "API key does not have image_generation permission", @@ -130,7 +165,7 @@ export default function DocsPage() {

POST /v1/chat/completions

OpenAI-compatible chat completions endpoint with enhanced features:

- + {`{ "messages": [ {"role": "user", "content": "Hello, how are you?"} @@ -155,7 +190,7 @@ export default function DocsPage() {

POST /v1/responses

Alternative endpoint supporting both single input and conversation format:

- + {`// Single input format { "input": "Explain quantum computing in simple terms", @@ -178,7 +213,7 @@ export default function DocsPage() {

Legacy endpoint for text generation, maintained for backward compatibility.

Response Format

- + {`{ "id": "chatcmpl-123abc", "object": "chat.completion", @@ -204,7 +239,7 @@ export default function DocsPage() {

Streaming Responses

When stream: true, responses are sent as Server-Sent Events:

- + {`data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1702587897,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]} data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1702587897,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":"stop"}]} @@ -261,7 +296,7 @@ data: [DONE]`}

POST /v1/images/generations

OpenAI-compatible image generation endpoint with enhanced parameters:

- + {`{ "prompt": "A majestic dragon soaring through clouds at sunset, digital art", "model": "nai-diffusion-3", @@ -295,13 +330,13 @@ data: [DONE]`}

DELETE /v1/images/:imageId

Delete a generated image (only images you created):

- + {`curl -X DELETE https://api.serika.dev/api/openai/v1/images/your-image-id \\ -H "Authorization: Bearer sk-your-api-key"`}

Response Format

- + {`{ "created": 1702587897, "data": [ @@ -343,20 +378,20 @@ data: [DONE]`}

GET /v1/characters

List all public characters (requires character_info permission):

- + {`curl https://api.serika.dev/api/openai/v1/characters \\ -H "Authorization: Bearer sk-your-api-key"`}

GET /v1/characters/:id

Get detailed information about a specific character:

- + {`curl https://api.serika.dev/api/openai/v1/characters/character-uuid \\ -H "Authorization: Bearer sk-your-api-key"`}

Character Response Format

- + {`{ "id": "character-uuid", "name": "Character Name", @@ -373,7 +408,7 @@ data: [DONE]`}

Using Characters in Text Generation

Include the character_id parameter in text generation requests:

- + {`{ "messages": [ {"role": "user", "content": "Hello! How are you today?"} @@ -389,7 +424,7 @@ data: [DONE]`}

POST /v1/keys

Create a new API key (requires authentication):

- + {`{ "name": "My Project Key" }`} @@ -400,7 +435,7 @@ data: [DONE]`}

PUT /v1/keys/:id/permissions

Update API key permissions:

- + {`{ "permissions": [ "text_generation", @@ -423,7 +458,7 @@ data: [DONE]`}

GET /v1/usage

Get detailed usage statistics:

- + {`curl "https://api.serika.dev/api/openai/v1/usage?startDate=2024-01-01&endDate=2024-01-31" \\ -H "Authorization: Bearer your-session-token"`} @@ -432,7 +467,7 @@ data: [DONE]`}

Setup usage-based billing for API access

Usage Response Format

- + {`{ "summary": { "totalTokens": 50000, @@ -697,7 +732,7 @@ data: [DONE]`}

SDKs and Libraries

The API is compatible with OpenAI SDKs. Simply change the base URL:

- + {`// JavaScript/Node.js const OpenAI = require('openai'); const client = new OpenAI({ diff --git a/src/app/dashboard/examples/page.tsx b/src/app/dashboard/examples/page.tsx index af32d7f..64b4f21 100644 --- a/src/app/dashboard/examples/page.tsx +++ b/src/app/dashboard/examples/page.tsx @@ -1,20 +1,55 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import React from 'react'; import DashboardLayout from '@/app/components/layout/DashboardLayout'; import Card from '@/app/components/ui/Card'; import { Tab } from '@headlessui/react'; -/* eslint-disable @typescript-eslint/ban-ts-comment */ -// @ts-ignore import SyntaxHighlighter from 'react-syntax-highlighter'; -/* eslint-enable @typescript-eslint/ban-ts-comment */ +import { useTheme } from '@/app/providers/ThemeProvider'; function classNames(...classes: string[]) { return classes.filter(Boolean).join(' '); } export default function ExamplesPage() { + const { theme } = useTheme(); + + // Custom purple Matrix-style theme + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const purpleMatrixTheme: any = { + 'hljs': { + display: 'block', + overflowX: 'auto', + padding: '1rem', + background: theme === 'dark' ? '#0a0a0a' : '#f8f8ff', + color: '#9d4edd', + borderRadius: '0.5rem' + }, + 'hljs-keyword': { color: '#c77dff' }, + 'hljs-string': { color: '#e0aaff' }, + 'hljs-number': { color: '#7b2cbf' }, + 'hljs-comment': { color: '#6c63ff', fontStyle: 'italic' }, + 'hljs-function': { color: '#8b5cf6' }, + 'hljs-variable': { color: '#a855f7' }, + 'hljs-property': { color: '#9333ea' }, + 'hljs-built_in': { color: '#7c3aed' }, + 'hljs-title': { color: '#6d28d9' }, + 'hljs-literal': { color: '#8b5cf6' }, + 'hljs-type': { color: '#7c3aed' }, + 'hljs-attribute': { color: '#9333ea' }, + 'hljs-meta': { color: '#6c63ff' }, + 'hljs-tag': { color: '#8b5cf6' }, + 'hljs-name': { color: '#a855f7' }, + 'hljs-attr': { color: '#9333ea' }, + 'hljs-selector-id': { color: '#7c3aed' }, + 'hljs-selector-class': { color: '#8b5cf6' }, + 'hljs-regexp': { color: '#c77dff' }, + 'hljs-link': { color: '#e0aaff' }, + 'hljs-symbol': { color: '#7b2cbf' }, + 'hljs-bullet': { color: '#9d4edd' }, + 'hljs-addition': { color: '#8b5cf6', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' }, + 'hljs-deletion': { color: '#7b2cbf', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' } + }; const examples = { javascript: { name: 'JavaScript', @@ -127,7 +162,7 @@ generate_text()`,
{example.code} diff --git a/src/app/dashboard/playground/page.tsx b/src/app/dashboard/playground/page.tsx index 095ab48..de4f1f7 100644 --- a/src/app/dashboard/playground/page.tsx +++ b/src/app/dashboard/playground/page.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import React, { useEffect, useState } from 'react'; @@ -10,13 +9,9 @@ import { Tab } from '@headlessui/react'; import { getModels, generateText, generateImage, getCharacters, setStoredApiKey, getStoredApiKey } from '@/app/services/api'; import { Model, Character, GenerationRequest, ImageGenerationRequest } from '@/app/types'; import { ArrowPathIcon, KeyIcon, ClipboardIcon } from '@heroicons/react/24/outline'; -// @ts-ignore import Editor from '@monaco-editor/react'; import Image from 'next/image'; -/* eslint-disable @typescript-eslint/ban-ts-comment */ -// @ts-ignore import SyntaxHighlighter from 'react-syntax-highlighter'; -/* eslint-enable @typescript-eslint/ban-ts-comment */ function classNames(...classes: string[]) { return classes.filter(Boolean).join(' '); @@ -24,6 +19,43 @@ function classNames(...classes: string[]) { export default function PlaygroundPage() { const { theme } = useTheme(); + + // Custom purple Matrix-style theme + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const purpleMatrixTheme: any = { + 'hljs': { + display: 'block', + overflowX: 'auto', + padding: '1rem', + background: theme === 'dark' ? '#0a0a0a' : '#f8f8ff', + color: '#9d4edd', + borderRadius: '0.5rem' + }, + 'hljs-keyword': { color: '#c77dff' }, + 'hljs-string': { color: '#e0aaff' }, + 'hljs-number': { color: '#7b2cbf' }, + 'hljs-comment': { color: '#6c63ff', fontStyle: 'italic' }, + 'hljs-function': { color: '#8b5cf6' }, + 'hljs-variable': { color: '#a855f7' }, + 'hljs-property': { color: '#9333ea' }, + 'hljs-built_in': { color: '#7c3aed' }, + 'hljs-title': { color: '#6d28d9' }, + 'hljs-literal': { color: '#8b5cf6' }, + 'hljs-type': { color: '#7c3aed' }, + 'hljs-attribute': { color: '#9333ea' }, + 'hljs-meta': { color: '#6c63ff' }, + 'hljs-tag': { color: '#8b5cf6' }, + 'hljs-name': { color: '#a855f7' }, + 'hljs-attr': { color: '#9333ea' }, + 'hljs-selector-id': { color: '#7c3aed' }, + 'hljs-selector-class': { color: '#8b5cf6' }, + 'hljs-regexp': { color: '#c77dff' }, + 'hljs-link': { color: '#e0aaff' }, + 'hljs-symbol': { color: '#7b2cbf' }, + 'hljs-bullet': { color: '#9d4edd' }, + 'hljs-addition': { color: '#8b5cf6', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' }, + 'hljs-deletion': { color: '#7b2cbf', backgroundColor: theme === 'dark' ? '#1a1a1a' : '#faf5ff' } + }; const [activeTab, setActiveTab] = useState(0); const [apiKey, setApiKeyLocal] = useState(''); const [loading, setLoading] = useState(false); @@ -211,6 +243,37 @@ export default function PlaygroundPage() { } }; + // Custom purple Matrix theme for Monaco Editor + const monacoTheme = { + base: theme === 'dark' ? 'vs-dark' : 'vs', + inherit: true, + rules: [ + { token: '', foreground: '9d4edd' }, + { token: 'string', foreground: 'e0aaff' }, + { token: 'number', foreground: '7b2cbf' }, + { token: 'keyword', foreground: 'c77dff' }, + { token: 'operator', foreground: '8b5cf6' }, + { token: 'delimiter', foreground: 'a855f7' }, + { token: 'comment', foreground: '6c63ff', fontStyle: 'italic' }, + { token: 'type', foreground: '7c3aed' }, + { token: 'variable', foreground: 'a855f7' }, + { token: 'function', foreground: '8b5cf6' }, + { token: 'property', foreground: '9333ea' }, + ], + colors: { + 'editor.background': theme === 'dark' ? '#0a0a0a' : '#f8f8ff', + 'editor.foreground': '#9d4edd', + 'editorCursor.foreground': '#c77dff', + 'editor.lineHighlightBackground': theme === 'dark' ? '#1a0d1a' : '#f0e6ff', + 'editor.selectionBackground': theme === 'dark' ? '#2d1b69' : '#e0aaff40', + 'editor.inactiveSelectionBackground': theme === 'dark' ? '#1a0d1a' : '#e0aaff20', + 'editorLineNumber.foreground': '#7b2cbf', + 'editorLineNumber.activeForeground': '#c77dff', + 'editorBracketMatch.background': theme === 'dark' ? '#2d1b69' : '#e0aaff60', + 'editorBracketMatch.border': '#c77dff', + } + }; + return ( @@ -393,9 +456,19 @@ export default function PlaygroundPage() { language="json" value={getMessagesEditorValue()} onChange={updateMessages} + theme="purple-matrix" + beforeMount={(monaco) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + monaco.editor.defineTheme('purple-matrix', monacoTheme as any); + }} options={{ minimap: { enabled: false }, scrollBeyondLastLine: false, + fontSize: 14, + fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace', + lineNumbers: 'on', + renderLineHighlight: 'line', + automaticLayout: true, }} />
@@ -668,11 +741,11 @@ export default function PlaygroundPage() { -
- +
+ {codeExamples[language as keyof typeof codeExamples]} -
+