Skip to content

Commit 96d34d9

Browse files
✨ Manage reports page
1 parent b65dc0b commit 96d34d9

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

pages/api/update-report.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { NextApiRequest, NextApiResponse } from 'next';
2+
import { getServerSession } from 'next-auth';
3+
import { authOptions } from './auth/[...nextauth]';
4+
import { getXataClient } from 'xata';
5+
6+
export default async function updateReport(
7+
req: NextApiRequest,
8+
res: NextApiResponse
9+
) {
10+
if (req.method === 'PUT') {
11+
const allowedEmails = [
12+
13+
14+
];
15+
const session = await getServerSession(req, res, authOptions);
16+
if (!session || !session.user) {
17+
return res.status(401).json({ message: 'You must be logged in.' });
18+
}
19+
if (!allowedEmails.includes(session.user.email!)) {
20+
return res.status(401).json({ message: 'Invalid user.' });
21+
}
22+
const client = getXataClient();
23+
const reportId = req.query.id as string;
24+
const report = await client.db.reports.filter({ id: reportId }).getFirst();
25+
if (!report) {
26+
return res.status(404).json({ message: 'Report not found' });
27+
}
28+
29+
const updatedReport = await client.db.reports.update(reportId, {
30+
valid: !report.valid
31+
});
32+
33+
return res.send(updatedReport);
34+
}
35+
}

pages/reports.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
2+
import { getServerSession } from 'next-auth';
3+
import { authOptions } from './api/auth/[...nextauth]';
4+
import { ReportsRecord, getXataClient } from 'xata';
5+
import { SelectedPick } from '@xata.io/client';
6+
import { ChangeEvent, useState } from 'react';
7+
import axios from 'axios';
8+
9+
interface ReportsPageProps {
10+
reports: Readonly<SelectedPick<ReportsRecord, ['*']>>[];
11+
}
12+
13+
export default function ReportsPage({ reports }: ReportsPageProps) {
14+
return (
15+
<div className="container mx-auto mb-10 mt-5">
16+
<h2 className="text-3xl text-center">Reports</h2>
17+
18+
<div className="grid gap-2 place-items-center grid-cols-1">
19+
{reports.map(report => (
20+
<ReportCard key={report.id} report={report} />
21+
))}
22+
</div>
23+
</div>
24+
);
25+
}
26+
27+
function ReportCard({
28+
report
29+
}: {
30+
report: ReportsPageProps['reports'][number];
31+
}) {
32+
const [isValid, setIsValid] = useState(report.valid);
33+
34+
async function handleToggleVisibility(e: ChangeEvent<HTMLInputElement>) {
35+
setIsValid(!isValid);
36+
const res = await axios.put(`/api/update-report?id=${report.id}`);
37+
if (res.status !== 200) setIsValid(!isValid);
38+
}
39+
40+
return (
41+
<div className="card w-full bg-base-100 shadow-xl">
42+
<div className="card-body">
43+
<a href={report.repoUrl!} className="link card-title" target="_blank">
44+
{report.repoUrl?.split('github.com/').at(1)}
45+
</a>
46+
<p>{report.message}</p>
47+
<div className="card-actions justify-end">
48+
{isValid ? 'Valid' : 'Invalid'}
49+
<input
50+
type="checkbox"
51+
className="toggle toggle-warning"
52+
checked={isValid}
53+
onChange={handleToggleVisibility}
54+
/>
55+
</div>
56+
</div>
57+
</div>
58+
);
59+
}
60+
61+
export async function getServerSideProps(
62+
context: GetServerSidePropsContext
63+
): Promise<GetServerSidePropsResult<ReportsPageProps>> {
64+
const allowedEmails = ['[email protected]', '[email protected]'];
65+
const session = await getServerSession(context.req, context.res, authOptions);
66+
67+
if (!session || !session.user) return { notFound: true };
68+
if (!allowedEmails.includes(session.user.email!)) return { notFound: true };
69+
70+
const client = getXataClient();
71+
const reports = JSON.parse(
72+
JSON.stringify(
73+
await client.db.reports.sort('xata.createdAt', 'desc').getAll()
74+
)
75+
);
76+
77+
return {
78+
props: { reports }
79+
};
80+
}

0 commit comments

Comments
 (0)