Skip to content

Commit

Permalink
work in progress for removing active protocol concept
Browse files Browse the repository at this point in the history
  • Loading branch information
jthrilly committed Jan 22, 2024
1 parent f200457 commit 09200a2
Show file tree
Hide file tree
Showing 32 changed files with 244 additions and 365 deletions.
81 changes: 81 additions & 0 deletions app/(dashboard)/dashboard/_components/AnonymousRecruitmentTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use client';

import type { Protocol } from '@prisma/client';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import RecruitmentSwitch from '~/components/RecruitmentSwitch';
import { Button } from '~/components/ui/Button';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '~/components/ui/select';
import { api } from '~/trpc/client';

const AnonymousRecruitmentTest = () => {
const { data: appSettings, isLoading: isLoadingAppSettings } =
api.appSettings.get.useQuery();
const { data: protocolData, isLoading: isLoadingProtocols } =
api.protocol.get.all.useQuery();
const [protocols, setProtocols] = useState<Protocol[]>([]);
const [selectedProtocol, setSelectedProtocol] = useState<Protocol>();

useEffect(() => {
if (protocolData) {
setProtocols(protocolData);
}
}, [protocolData]);

if (isLoadingAppSettings) {
return <div>Loading...</div>;
}

return (
<div className="flex flex-col gap-4 rounded-lg border border-muted p-6">
<h1 className="text-xl">Anonymous Recruitment Test Section</h1>
<div className="flex justify-between">
<p>Allow anonymous recruitment?</p>
<RecruitmentSwitch />
</div>
<div></div>
{appSettings?.allowAnonymousRecruitment && (
<div className="flex">
<Select
onValueChange={(value) => {
const protocol = protocols.find(
(protocol) => protocol.id.toString() === value,
);

setSelectedProtocol(protocol);
}}
value={selectedProtocol?.id.toString()}
disabled={isLoadingProtocols}
>
<SelectTrigger>
<SelectValue placeholder="Select a Protocol..." />
</SelectTrigger>
<SelectContent>
{protocols?.map((protocol) => (
<SelectItem key={protocol.id} value={protocol.id}>
{protocol.name}
</SelectItem>
))}
</SelectContent>
</Select>

{selectedProtocol && (
<Link href={`/onboard/${selectedProtocol?.id}`}>
<Button>
Start anonymous interview using {selectedProtocol.name}
</Button>
</Link>
)}
</div>
)}
</div>
);
};

export default AnonymousRecruitmentTest;

This file was deleted.

12 changes: 0 additions & 12 deletions app/(dashboard)/dashboard/_components/ProtocolsTable/Columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import { type ColumnDef, flexRender } from '@tanstack/react-table';
import { Checkbox } from '~/components/ui/checkbox';
import ActiveButton from './ActiveButton';
import { DataTableColumnHeader } from '~/components/DataTable/ColumnHeader';
import type { ProtocolWithInterviews } from '~/shared/types';
import { dateOptions } from '~/components/DataTable/helpers';
Expand All @@ -29,17 +28,6 @@ export const ProtocolColumns: ColumnDef<ProtocolWithInterviews>[] = [
enableSorting: false,
enableHiding: false,
},
{
id: 'active',
enableSorting: true,
accessorFn: (row) => row.active,
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Active" />
),
cell: ({ row }) => (
<ActiveButton active={row.original.active} protocolId={row.original.id} />
),
},
{
accessorKey: 'name',
header: ({ column }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ export const ProtocolsTable = ({
filterColumnAccessorKey="name"
handleDeleteSelected={handleDelete}
actions={ActionsDropdown}
calculateRowClasses={(row) =>
row.original.active
? 'bg-purple-500/30 hover:bg-purple-500/40'
: undefined
}
/>
<DeleteProtocolsDialog
open={showAlertDialog}
Expand Down
9 changes: 2 additions & 7 deletions app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import ResetButton from './_components/ResetButton';
import AnonymousRecruitmentSwitch from '~/components/AnonymousRecruitmentSwitch/AnonymousRecruitmentSwitch';
import Link from 'next/link';
import { Button } from '~/components/ui/Button';
import AnalyticsButton from './_components/AnalyticsButton';
import AnonymousRecruitmentTest from './_components/AnonymousRecruitmentTest';

function Home() {
return (
<>
<main className="mx-auto flex w-[80%] max-w-[1200px] flex-col gap-10 p-10">
<h1 className="mb-2 text-3xl font-bold">Welcome</h1>
<p>This is the main dashboard.</p>
<Link href="/interview/new">
<Button>Start anonymous interview</Button>
</Link>
<ResetButton />
<AnonymousRecruitmentSwitch />
<AnonymousRecruitmentTest />
<AnalyticsButton />
</main>
</>
Expand Down
72 changes: 0 additions & 72 deletions app/(interview)/interview/new/page.tsx

This file was deleted.

11 changes: 11 additions & 0 deletions app/(interview)/interview/no-anonymous-recruitment/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ErrorMessage } from '../_components/ErrorMessage';

export default function Page() {
return (
<ErrorMessage
title="Anonymous Recruitment Disabled"
message="Anonymous recruitment is disabled for this study. Researchers may
optionally enable anonymous recruitment from the dashboard"
/>
);
}
73 changes: 73 additions & 0 deletions app/(interview)/onboard/[protocolId]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { faker } from '@faker-js/faker';
import { NextResponse, type NextRequest } from 'next/server';
import { api } from '~/trpc/server';

export const dynamic = 'force-dynamic'; // defaults to auto

const handler = async (
req: NextRequest,
{ params }: { params: { protocolId: string } },
) => {
const protocolId = params.protocolId; // From route segment
let postData = undefined;

// We need to check the request method to see if we should parse the body - it
// fails on GET requests.
if (req.method === 'POST') {
postData = (await req.json()) as { participantId?: string } | undefined;
}

const searchParams = req.nextUrl.searchParams;

let participantId =
searchParams.get('participantId') ?? postData?.participantId;

// If no participant ID is provided in searchParams or request body, check
// if anonymous recruitment is enabled to see if we should generate one.
if (!participantId) {
const appSettings = await api.appSettings.get.query();

if (!appSettings || !appSettings.allowAnonymousRecruitment) {
return NextResponse.redirect(
new URL('/interview/no-anonymous-recruitment', req.nextUrl),
);
}

// Generate a participantID - this will be used as a **identifier** rather
// than an ID.
participantId = faker.string.uuid();

// eslint-disable-next-line no-console
console.log(
`🕵️🚫 No participantID provided. Generated a new identifier: ${participantId}.`,
);
} else {
// eslint-disable-next-line no-console
console.log(`🕵️✅ Using provided participantID: ${participantId}.`);
}

// Create a new interview given the protocolId and participantId
const { createdInterviewId, error } = await api.interview.create.mutate({
participantId,
protocolId,
});

if (error) {
return NextResponse.json(
{ error: 'Failed to create interview', errorType: error },
{ status: 500 },
);
}

// eslint-disable-next-line no-console
console.log(
`🚀 Starting interview with ID ${createdInterviewId} and protocol ${protocolId}...`,
);

// Redirect to the interview
return NextResponse.redirect(
new URL(`/interview/${createdInterviewId}`, req.nextUrl),
);
};

export { handler as GET, handler as POST };
17 changes: 0 additions & 17 deletions app/(interview)/participant/[participantId]/page.tsx

This file was deleted.

File renamed without changes.
Loading

0 comments on commit 09200a2

Please sign in to comment.