Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to next 15 #268

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
401d3c9
add protocol validation lib
jthrilly Nov 28, 2024
7d273b7
inline protocol-validation lib
jthrilly Nov 29, 2024
3fc3ab0
protocol-validation tests
jthrilly Nov 29, 2024
014a9eb
update snapshots
jthrilly Nov 29, 2024
a9f5434
add todo for missing migration tests
jthrilly Nov 29, 2024
d799027
reorganize schemas and add scripts to package.json
jthrilly Nov 29, 2024
5ffbde1
add test protocol
jthrilly Nov 29, 2024
29bf413
ignore protocol-validation ts errors for now
jthrilly Nov 29, 2024
ae6953b
fix outstanding errors relating to protocol validation lib
jthrilly Dec 2, 2024
5a5dcb9
Merge branch 'next' into schema-8
jthrilly Dec 5, 2024
a12afae
Merge branch 'main' into schema-8
jthrilly Dec 5, 2024
2ff4c0e
update pnpm lock
jthrilly Dec 5, 2024
0535589
run codemod
jthrilly Jan 15, 2025
09197b0
Bump nanoid in the npm_and_yarn group across 1 directory
dependabot[bot] Jan 15, 2025
ba815ee
add eslint config to linting to prepare for eslint 9 upgrade
jthrilly Jan 15, 2025
757268e
Fix typo
jthrilly Jan 15, 2025
4b835f4
remove auth
jthrilly Jan 15, 2025
10edc6e
migrate to ts config
jthrilly Jan 15, 2025
6601eba
async destructuring of route params and removing direct import of mp3…
jthrilly Jan 15, 2025
16e1032
Merge pull request #267 from complexdatacollective/jthrilly-patch-1
jthrilly Jan 15, 2025
4f714aa
improve stage error boundary
jthrilly Jan 15, 2025
f0b95c4
WIP tear out drag and drop system
jthrilly Jan 15, 2025
04128bf
Merge pull request #266 from complexdatacollective/dependabot/npm_and…
jthrilly Jan 15, 2025
5cebd70
sync with next
jthrilly Jan 16, 2025
f6be250
change the way reset is called to bypass TS error
jthrilly Jan 16, 2025
87b983c
update redux, redux toolkit, and typescript errors related to react a…
jthrilly Jan 16, 2025
caa6b41
remove deviceSettings entirely; switch build action to run on node 22
jthrilly Jan 16, 2025
d5f8ed0
bring changes from schema-8
jthrilly Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const path = require('path');

/** @type {import("eslint").Linter.Config} */
const config = {
overrides: [
Expand All @@ -10,13 +8,13 @@ const config = {
],
files: ['*.ts', '*.tsx'],
parserOptions: {
project: path.join(__dirname, 'tsconfig.json'),
project: true, // This tells ESLint to automatically detect the tsconfig
},
},
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: path.join(__dirname, 'tsconfig.json'),
project: true, // This tells ESLint to automatically detect the tsconfig
},
plugins: ['@typescript-eslint'],
extends: [
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
- name: Enable Corepack
run: corepack enable

- name: Use Node 20.x
- name: Use Node 22.x
uses: actions/setup-node@v4
with:
node-version: 20.x
node-version: 22.x
cache: 'pnpm'

- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion actions/activityFeed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use sever';
'use server';

import { safeRevalidateTag } from '~/lib/cache';
import type { Activity, ActivityType } from '~/lib/data-table/types';
Expand Down
65 changes: 3 additions & 62 deletions actions/auth.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use server';

import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { createUserFormDataSchema, loginSchema } from '~/schemas/auth';
import { auth, getServerSession } from '~/utils/auth';
import { getServerSession } from '~/utils/auth';
import { prisma } from '~/utils/db';

// eslint-disable-next-line @typescript-eslint/require-await
export async function signup(formData: unknown) {
const parsedFormData = createUserFormDataSchema.safeParse(formData);

Expand All @@ -18,41 +18,6 @@ export async function signup(formData: unknown) {
}

try {
const { username, password } = parsedFormData.data;

const user = await auth.createUser({
key: {
providerId: 'username', // auth method
providerUserId: username, // unique id when using "username" auth method
password, // hashed by Lucia
},
attributes: {
username,
},
});

const session = await auth.createSession({
userId: user.userId,
attributes: {},
});

if (!session) {
return {
success: false,
error: 'Failed to create session',
};
}

// set session cookie

const sessionCookie = auth.createSessionCookie(session);

cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);

redirect('/setup?step=2');
} catch (error) {
// db error, email taken, etc
Expand Down Expand Up @@ -84,7 +49,7 @@ export const login = async (
};
}

const { username, password } = parsedFormData.data;
const { username } = parsedFormData.data;

// get user by userId
const existingUser = await prisma.user.findFirst({
Expand All @@ -111,28 +76,6 @@ export const login = async (
};
}

let key;
try {
key = await auth.useKey('username', username, password);
} catch (e) {
return {
success: false,
formErrors: ['Incorrect username or password'],
};
}

const session = await auth.createSession({
userId: key.userId,
attributes: {},
});

const sessionCookie = auth.createSessionCookie(session);
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);

return {
success: true,
};
Expand All @@ -146,7 +89,5 @@ export async function logout() {
};
}

await auth.invalidateSession(session.sessionId);

revalidatePath('/');
}
2 changes: 1 addition & 1 deletion actions/interviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export async function finishInterview(interviewId: Interview['id']) {
},
});

cookies().set(updatedInterview.protocolId, 'completed');
(await cookies()).set(updatedInterview.protocolId, 'completed');

safeRevalidateTag('getInterviews');
safeRevalidateTag('summaryStatistics');
Expand Down
4 changes: 2 additions & 2 deletions app/(blobs)/expired/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default async function Page() {
Please redeploy a new instance of Fresco to continue using the software.
</p>
{env.NODE_ENV === 'development' && (
<form action={resetAppSettings}>
<SubmitButton className="mt-6 max-w-[20rem]" type="submit">
<form action={void resetAppSettings}>
<SubmitButton className="mt-6 max-w-[20rem]">
Dev mode: Reset Configuration
</SubmitButton>
</form>
Expand Down
17 changes: 9 additions & 8 deletions app/(interview)/interview/[interviewId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import { notFound, redirect } from 'next/navigation';
import { syncInterview } from '~/actions/interviews';
import FeedbackBanner from '~/components/Feedback/FeedbackBanner';
import { getAppSetting } from '~/queries/appSettings';
import { getInterviewById } from '~/queries/interviews';
import { TESTING_getInterviewById } from '~/queries/interviews';
import { getServerSession } from '~/utils/auth';
import InterviewShell from '../_components/InterviewShell';

export default async function Page({
params,
}: {
params: { interviewId: string };
}) {
export default async function Page(
props: {
params: Promise<{ interviewId: string }>;
}
) {
const params = await props.params;
const { interviewId } = params;

if (!interviewId) {
return 'No interview id found';
}

const interview = await getInterviewById(interviewId);
const interview = await TESTING_getInterviewById(interviewId);
const session = await getServerSession();

// If the interview is not found, redirect to the 404 page
Expand All @@ -31,7 +32,7 @@ export default async function Page({
// and redirect to finished page
const limitInterviews = await getAppSetting('limitInterviews');

if (limitInterviews && cookies().get(interview?.protocol?.id ?? '')) {
if (limitInterviews && (await cookies()).get(interview?.protocol?.id ?? '')) {
redirect('/interview/finished');
}

Expand Down
6 changes: 3 additions & 3 deletions app/(interview)/onboard/[protocolId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export const dynamic = 'force-dynamic';

const handler = async (
req: NextRequest,
{ params }: { params: { protocolId: string } },
{ params }: { params: Promise<{ protocolId: string }> },
) => {
const protocolId = params.protocolId; // From route segment
const protocolId = (await params).protocolId; // From route segment

// when deployed via docker `req.url` and `req.nextUrl`
// shows Docker Container ID instead of real host
Expand All @@ -30,7 +30,7 @@ const handler = async (
// if limitInterviews is enabled
// Check cookies for interview already completed for this user for this protocol
// and redirect to finished page
if (limitInterviews && cookies().get(protocolId)) {
if (limitInterviews && (await cookies()).get(protocolId)) {
url.pathname = '/interview/finished';
return NextResponse.redirect(url);
}
Expand Down
2 changes: 1 addition & 1 deletion app/dashboard/_components/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SubmitButton from '~/components/ui/SubmitButton';

const UserMenu = () => {
return (
<form action={() => logout()}>
<form action={void logout}>
<SubmitButton variant="secondary" size="sm" type="submit">
Sign out
</SubmitButton>
Expand Down
11 changes: 6 additions & 5 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import SummaryStatistics from './_components/SummaryStatistics/SummaryStatistics
import UpdateUploadThingTokenAlert from './_components/UpdateUploadThingTokenAlert';
import AnonymousRecruitmentWarning from './protocols/_components/AnonymousRecruitmentWarning';

export default async function Home({
searchParams,
}: {
searchParams: Record<string, string | string[] | undefined>;
}) {
export default async function Home(
props: {
searchParams: Promise<Record<string, string | string[] | undefined>>;
}
) {
const searchParams = await props.searchParams;
await requireAppNotExpired();
await requirePageAuth();

Expand Down
9 changes: 0 additions & 9 deletions auth.d.ts

This file was deleted.

4 changes: 2 additions & 2 deletions components/Feedback/SignOutModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { type Dispatch, type SetStateAction } from 'react';
import { logout } from '~/actions/auth';
import {
AlertDialog,
AlertDialogAction,
Expand All @@ -11,7 +12,6 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from '../ui/AlertDialog';
import { logout } from '~/actions/auth';

type SignOutModalProps = {
openSignOutModal: boolean;
Expand Down Expand Up @@ -39,7 +39,7 @@ const SignOutModal = ({
<AlertDialogCancel onClick={() => setOpenSignOutModal(false)}>
Cancel
</AlertDialogCancel>
<AlertDialogAction onClick={() => void logout()}>
<AlertDialogAction onClick={logout}>
Sign Out and Hide Banner
</AlertDialogAction>
</AlertDialogFooter>
Expand Down
2 changes: 2 additions & 0 deletions env.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const env = createEnv({
POSTGRES_PRISMA_URL: z.string(),
POSTGRES_URL_NON_POOLING: z.string(),
PUBLIC_URL: z.string().url().optional(),
SIMULATE_DELAY: strictBooleanSchema.optional(),
},

/**
Expand Down Expand Up @@ -53,6 +54,7 @@ export const env = createEnv({
SANDBOX_MODE: process.env.SANDBOX_MODE,
APP_VERSION: process.env.APP_VERSION,
COMMIT_HASH: process.env.COMMIT_HASH,
SIMULATE_DELAY: process.env.SIMULATE_DELAY,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
Expand Down
4 changes: 2 additions & 2 deletions hooks/useCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useRef, useEffect } from 'react';

const resizeCanvas = (
context: CanvasRenderingContext2D,
canvasRef: React.RefObject<HTMLCanvasElement>,
canvasRef: React.RefObject<HTMLCanvasElement | null>,
) => {
if (!canvasRef?.current) {
return false;
Expand All @@ -29,7 +29,7 @@ const resizeCanvas = (
type DrawFunction = (
ctx: CanvasRenderingContext2D,
time: number,
canvasRef: React.RefObject<HTMLCanvasElement>,
canvasRef: React.RefObject<HTMLCanvasElement | null>,
) => void;

const defaultPredraw: DrawFunction = (context: CanvasRenderingContext2D) => {
Expand Down
2 changes: 1 addition & 1 deletion hooks/usePrevious.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react';

export default function usePrevious(value: unknown) {
const ref = useRef<unknown>();
const ref = useRef<unknown>(undefined);
useEffect(() => {
ref.current = value;
});
Expand Down
4 changes: 2 additions & 2 deletions hooks/useProtocolImport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const useProtocolImport = () => {
return;
}

const { validateProtocol } = await import('@codaco/protocol-validation');
const { validateProtocol } = await import('~/lib/protocol-validation');

const validationResult = await validateProtocol(protocolJson);

Expand Down Expand Up @@ -130,7 +130,7 @@ export const useProtocolImport = () => {
...validationResult.logicErrors,
].map((validationError, i) => (
<li className="flex capitalize" key={i}>
<XCircle className="mr-2 h-4 w-4 text-destructive" />
<XCircle className="text-destructive mr-2 h-4 w-4" />
<span>
{validationError.message}{' '}
<span className="text-xs italic">
Expand Down
2 changes: 1 addition & 1 deletion hooks/useResizeObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type RefObject, useEffect } from 'react';

const useResizeObserver = <T extends HTMLElement>(
callback: ResizeObserverCallback,
elementRef: RefObject<T>,
elementRef: RefObject<T | null>,
options?: ResizeObserverOptions,
) => {
useEffect(() => {
Expand Down
11 changes: 10 additions & 1 deletion knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
"lib/interviewer/hooks/forceSimulation.worker.js",
"lib/ui/components/Sprites/ExportSprite.js",
"utils/auth.ts",
"load-test.js"
"load-test.js",
"lib/protocol-validation/schemas/compiled/index.js",
"lib/protocol-validation/schemas/compiled/1.js",
"lib/protocol-validation/schemas/compiled/2.js",
"lib/protocol-validation/schemas/compiled/3.js",
"lib/protocol-validation/schemas/compiled/4.js",
"lib/protocol-validation/schemas/compiled/5.js",
"lib/protocol-validation/schemas/compiled/6.js",
"lib/protocol-validation/schemas/compiled/7.js",
"lib/protocol-validation/schemas/compiled/8.js"
],
"ignoreDependencies": [
"server-only",
Expand Down
Loading
Loading