mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-20 18:43:20 +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.
66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
import { Link } from '@inertiajs/react';
|
|
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { useFormatDate } from '@/hooks/use-format-date';
|
|
import { useTranslation } from '@/hooks/use-translation';
|
|
|
|
export interface ApiUsageSummary {
|
|
requests_7d: number;
|
|
tokens: number;
|
|
expired_tokens: number;
|
|
last_used_at: string | null;
|
|
}
|
|
|
|
/**
|
|
* The viewer's own API usage at a glance. Scoped to their own tokens, like
|
|
* the API dashboard it links to — a widget everyone sees must not become a
|
|
* window onto colleagues' integrations.
|
|
*/
|
|
export function ApiWidget({ summary }: { summary: ApiUsageSummary }) {
|
|
const { t } = useTranslation();
|
|
|
|
const { date } = useFormatDate();
|
|
|
|
if (summary.tokens === 0) {
|
|
return (
|
|
<div className="space-y-3">
|
|
<p className="text-muted-foreground text-sm">{t('You have no API tokens. Create one to let an external tool act on your behalf.')}</p>
|
|
<Button variant="outline" size="sm" asChild>
|
|
<Link href="/settings/api-tokens/create">{t('Create token')}</Link>
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<p className="text-muted-foreground text-xs font-medium">{t('Requests (7 days)')}</p>
|
|
<p className="mt-1 text-2xl font-semibold tabular-nums">{summary.requests_7d}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-muted-foreground text-xs font-medium">{t('Tokens')}</p>
|
|
<p className="mt-1 flex items-center gap-2 text-2xl font-semibold tabular-nums">
|
|
{summary.tokens}
|
|
{summary.expired_tokens > 0 && (
|
|
<Badge variant="destructive" className="text-xs">
|
|
{t(':count expired', { count: summary.expired_tokens })}
|
|
</Badge>
|
|
)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<p className="text-muted-foreground text-xs">
|
|
{summary.last_used_at ? t('Last used :date', { date: date(summary.last_used_at) }) : t('Never used')}
|
|
</p>
|
|
|
|
<Button variant="ghost" size="sm" asChild className="px-0">
|
|
<Link href="/api">{t('Open the API dashboard')}</Link>
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|