mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-21 11:03:19 +00:00
6e47d76ba6
Client file sharing, rebuilt from the ground up: a private area per client, resumable uploads, folders, groups and categories, sharing with expiry dates and download limits, comments, file versions, an activity log, a REST API, and sixteen languages. This repository begins here. ProjectSend 2 was developed privately, and that development history is not published — the previous generation remains available, with its own history, at projectsend/legacy. Free software under the GNU General Public License v2, or (at your option) any later version.
97 lines
4.4 KiB
TypeScript
97 lines
4.4 KiB
TypeScript
import { Head, Link } from '@inertiajs/react';
|
|
|
|
import Heading from '@/components/heading';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { useTranslation } from '@/hooks/use-translation';
|
|
import AppLayout from '@/layouts/app-layout';
|
|
import { type BreadcrumbItem } from '@/types';
|
|
|
|
interface Endpoint {
|
|
method: string;
|
|
path: string;
|
|
summary: string;
|
|
abilities: string[];
|
|
}
|
|
|
|
interface Props {
|
|
guide_html: string;
|
|
endpoints: Endpoint[];
|
|
spec_url: string;
|
|
version: string | null;
|
|
}
|
|
|
|
const METHOD_TONE: Record<string, string> = {
|
|
GET: 'text-emerald-700 dark:text-emerald-400',
|
|
POST: 'text-violet-700 dark:text-violet-400',
|
|
PATCH: 'text-amber-700 dark:text-amber-400',
|
|
PUT: 'text-amber-700 dark:text-amber-400',
|
|
DELETE: 'text-red-700 dark:text-red-400',
|
|
};
|
|
|
|
export default function ApiDocs({ guide_html, endpoints, spec_url, version }: Props) {
|
|
const { t } = useTranslation();
|
|
|
|
const breadcrumbs: BreadcrumbItem[] = [{ title: t('API'), href: '/api/docs' }];
|
|
|
|
return (
|
|
<AppLayout breadcrumbs={breadcrumbs}>
|
|
<Head title={t('API')} />
|
|
|
|
<div className="px-4 py-6">
|
|
<div className="flex flex-wrap items-start justify-between gap-4">
|
|
<Heading title={t('API')} description={t('How external tools can act on this installation on your behalf.')} />
|
|
<div className="flex items-center gap-2">
|
|
{version && <Badge variant="secondary">v{version}</Badge>}
|
|
<Button variant="outline" size="sm" asChild>
|
|
<a href={spec_url} target="_blank" rel="noreferrer">
|
|
{t('OpenAPI specification')}
|
|
</a>
|
|
</Button>
|
|
<Button size="sm" asChild>
|
|
<Link href={route('api-tokens.index')}>{t('API tokens')}</Link>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<section className="mb-10">
|
|
<h2 className="mb-3 text-base font-semibold">{t('Endpoints')}</h2>
|
|
<div className="overflow-x-auto rounded-md border">
|
|
<table className="w-full text-sm">
|
|
<thead className="bg-muted/50">
|
|
<tr className="text-left">
|
|
<th className="px-4 py-2 font-medium">{t('Method')}</th>
|
|
<th className="px-4 py-2 font-medium">{t('Path')}</th>
|
|
<th className="px-4 py-2 font-medium">{t('Description')}</th>
|
|
<th className="px-4 py-2 font-medium">{t('Permissions')}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{endpoints.map((endpoint) => (
|
|
<tr key={`${endpoint.method} ${endpoint.path}`} className="border-t">
|
|
<td className={`px-4 py-2 font-mono text-xs font-semibold ${METHOD_TONE[endpoint.method] ?? ''}`}>
|
|
{endpoint.method}
|
|
</td>
|
|
<td className="px-4 py-2 font-mono text-xs whitespace-nowrap">{endpoint.path}</td>
|
|
<td className="text-muted-foreground px-4 py-2">{endpoint.summary}</td>
|
|
<td className="px-4 py-2">
|
|
<span className="text-muted-foreground font-mono text-xs">{endpoint.abilities.join(', ') || '—'}</span>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
{/*
|
|
* Rendered server-side from docs/api-guide.md, a file that
|
|
* ships with the application — see ApiDocsController, which
|
|
* converts it with HTML input escaped.
|
|
*/}
|
|
<section className="api-guide max-w-3xl" dangerouslySetInnerHTML={{ __html: guide_html }} />
|
|
</div>
|
|
</AppLayout>
|
|
);
|
|
}
|