Skip to content

Commit 0cf9ab9

Browse files
committed
feat: add badge
1 parent 53d0881 commit 0cf9ab9

File tree

5 files changed

+55
-17
lines changed

5 files changed

+55
-17
lines changed

src/graphql/context.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import { ServerResponse } from 'http';
2-
31
import { PrismaClient } from '@prisma/client';
42
import { WebhookService } from 'app/services/WebhookService';
3+
import { NextApiRequest, NextApiResponse } from 'next';
54

65
import { prisma } from '../lib/prisma/prisma';
76
import { EventService } from '../services/EventService';
87
import { TraceService } from '../services/TraceService';
98
import { UserService } from '../services/UserService';
109
import { WebsiteService } from '../services/WebsiteService';
11-
import type { NextIncomingMessage, RequestObjectHandler } from '../utils/types';
10+
import type { RequestObjectHandler } from '../utils/types';
1211
import { Auth, AuthInfo } from './auth';
1312

1413
export type Context = {
1514
authInfo?: AuthInfo;
15+
exemptAuth?: boolean;
1616
prisma: PrismaClient;
1717
isLoggedIn: boolean;
1818
userService: UserService;
1919
eventService: EventService;
2020
websiteService: WebsiteService;
2121
traceService: TraceService;
2222
webhookService: WebhookService;
23-
req: NextIncomingMessage;
24-
res: ServerResponse;
23+
req: NextApiRequest;
24+
res: NextApiResponse;
2525
};
2626

2727
const auth = new Auth();

src/pages/api/badge/[id].ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createContext } from 'app/graphql/context';
2+
import { RequestHandler } from 'app/utils/types';
3+
4+
import { TraceStatus } from '.prisma/client';
5+
6+
export default (async (req, res) => {
7+
const context = await createContext({ req, res });
8+
context.exemptAuth = true;
9+
10+
const { id, rangeTime = '24h' } = req.query as { id: string; rangeTime?: string };
11+
12+
const result = await context.traceService.findTraces({ websiteId: parseInt(id), rangeTime });
13+
14+
const oks = result.results.filter((r) => r.status === TraceStatus.OK);
15+
16+
const percent =
17+
result.results.length === 0
18+
? 'unknown'
19+
: (Math.floor((oks.length / result.results.length) * 1000) / 1000) * 100;
20+
21+
const color =
22+
percent === 'unknown'
23+
? 'inactive'
24+
: percent >= 100
25+
? 'brightgreen'
26+
: percent >= 90
27+
? 'important'
28+
: 'critical';
29+
30+
res.redirect(`https://img.shields.io/badge/uptime-${encodeURIComponent(percent + '%')}-${color}`);
31+
}) as RequestHandler;

src/pages/monitoring/websiteStatus/[id].tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ export default function Page() {
117117
{website.data?.website.webhooks.length}
118118
</Descriptions.Item>
119119
)}
120+
121+
<Descriptions.Item label="Badge">
122+
<img
123+
src={`/api/badge/${website.data?.website?.id}`}
124+
alt="The shield"
125+
className="cursor-pointer"
126+
onClick={async () => {
127+
await navigator.clipboard.writeText(
128+
`[![uptime-monitor](${location.origin}/api/badge/${website.data?.website?.id})](${location.origin}/monitoring/websiteStatus/${website.data?.website?.id})`,
129+
);
130+
alert('Markdown copied!');
131+
}}
132+
/>
133+
</Descriptions.Item>
120134
</Descriptions>
121135

122136
<Link

src/services/TraceService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export class TraceService extends BaseService {
243243
const whereWithId = {
244244
...cursorWhere,
245245
...where,
246-
userId: this.ctx.authInfo!.id,
246+
userId: this.ctx.exemptAuth ? undefined : this.ctx.authInfo!.id,
247247
} as const;
248248

249249
const minId = (

src/utils/types.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
import { ServerResponse, IncomingMessage } from 'http';
2-
31
import * as t from 'io-ts';
2+
import type { NextApiRequest, NextApiResponse } from 'next';
43

54
import { NexusGenInputs } from '../../graphql/server/generated';
65

7-
export type NextIncomingMessage = IncomingMessage & {
8-
cookies?: {
9-
[key: string]: any;
10-
};
11-
};
12-
13-
export type RequestHandler = (req: NextIncomingMessage, res: ServerResponse) => Promise<void>;
6+
export type RequestHandler = (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
147

158
export type RequestObjectHandler<T = undefined> = (o: {
16-
req: NextIncomingMessage;
17-
res: ServerResponse;
9+
req: NextApiRequest;
10+
res: NextApiResponse;
1811
}) => Promise<T>;
1912

2013
export type InputObjectNames = keyof NexusGenInputs;

0 commit comments

Comments
 (0)