diff --git a/apps/portal/prisma/migrations/20221007135344_remove_resumes_profile_model/migration.sql b/apps/portal/prisma/migrations/20221007135344_remove_resumes_profile_model/migration.sql new file mode 100644 index 00000000..5b9baead --- /dev/null +++ b/apps/portal/prisma/migrations/20221007135344_remove_resumes_profile_model/migration.sql @@ -0,0 +1,73 @@ +/* + Warnings: + + - You are about to drop the column `resumesProfileId` on the `ResumesComment` table. All the data in the column will be lost. + - You are about to drop the column `resumesProfileId` on the `ResumesCommentVote` table. All the data in the column will be lost. + - You are about to drop the column `resumesProfileId` on the `ResumesResume` table. All the data in the column will be lost. + - You are about to drop the column `resumesProfileId` on the `ResumesStar` table. All the data in the column will be lost. + - You are about to drop the `ResumesProfile` table. If the table is not empty, all the data it contains will be lost. + - A unique constraint covering the columns `[userId,commentId]` on the table `ResumesCommentVote` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[userId,resumeId]` on the table `ResumesStar` will be added. If there are existing duplicate values, this will fail. + - Added the required column `userId` to the `ResumesComment` table without a default value. This is not possible if the table is not empty. + - Added the required column `userId` to the `ResumesCommentVote` table without a default value. This is not possible if the table is not empty. + - Added the required column `userId` to the `ResumesResume` table without a default value. This is not possible if the table is not empty. + - Added the required column `userId` to the `ResumesStar` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "ResumesComment" DROP CONSTRAINT "ResumesComment_resumesProfileId_fkey"; + +-- DropForeignKey +ALTER TABLE "ResumesCommentVote" DROP CONSTRAINT "ResumesCommentVote_resumesProfileId_fkey"; + +-- DropForeignKey +ALTER TABLE "ResumesProfile" DROP CONSTRAINT "ResumesProfile_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "ResumesResume" DROP CONSTRAINT "ResumesResume_resumesProfileId_fkey"; + +-- DropForeignKey +ALTER TABLE "ResumesStar" DROP CONSTRAINT "ResumesStar_resumesProfileId_fkey"; + +-- DropIndex +DROP INDEX "ResumesCommentVote_commentId_resumesProfileId_key"; + +-- DropIndex +DROP INDEX "ResumesStar_resumeId_resumesProfileId_key"; + +-- AlterTable +ALTER TABLE "ResumesComment" DROP COLUMN "resumesProfileId", +ADD COLUMN "userId" TEXT NOT NULL; + +-- AlterTable +ALTER TABLE "ResumesCommentVote" DROP COLUMN "resumesProfileId", +ADD COLUMN "userId" TEXT NOT NULL; + +-- AlterTable +ALTER TABLE "ResumesResume" DROP COLUMN "resumesProfileId", +ADD COLUMN "userId" TEXT NOT NULL; + +-- AlterTable +ALTER TABLE "ResumesStar" DROP COLUMN "resumesProfileId", +ADD COLUMN "userId" TEXT NOT NULL; + +-- DropTable +DROP TABLE "ResumesProfile"; + +-- CreateIndex +CREATE UNIQUE INDEX "ResumesCommentVote_userId_commentId_key" ON "ResumesCommentVote"("userId", "commentId"); + +-- CreateIndex +CREATE UNIQUE INDEX "ResumesStar_userId_resumeId_key" ON "ResumesStar"("userId", "resumeId"); + +-- AddForeignKey +ALTER TABLE "ResumesResume" ADD CONSTRAINT "ResumesResume_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ResumesStar" ADD CONSTRAINT "ResumesStar_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ResumesComment" ADD CONSTRAINT "ResumesComment_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ResumesCommentVote" ADD CONSTRAINT "ResumesCommentVote_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index 086eb2bc..7ece9c5d 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -37,15 +37,18 @@ model Session { } model User { - id String @id @default(cuid()) - name String? - email String? @unique - emailVerified DateTime? - image String? - accounts Account[] - sessions Session[] - todos Todo[] - resumesProfile ResumesProfile? + id String @id @default(cuid()) + name String? + email String? @unique + emailVerified DateTime? + image String? + accounts Account[] + sessions Session[] + todos Todo[] + resumesResumes ResumesResume[] + resumesStars ResumesStar[] + resumesComments ResumesComment[] + resumesCommentVotes ResumesCommentVote[] } model VerificationToken { @@ -85,56 +88,45 @@ model Company { // Add Resumes project models here, prefix all models with "Resumes", // use camelCase for field names, and try to name them consistently // across all models in this file. - -model ResumesProfile { - id String @id @default(cuid()) - userId String @unique - resumesResumes ResumesResume[] - resumesStars ResumesStar[] - resumesComments ResumesComment[] - resumesCommentVotes ResumesCommentVote[] - user User @relation(fields: [userId], references: [id], onDelete: Cascade) -} - model ResumesResume { - id String @id @default(cuid()) - resumesProfileId String - title String @db.Text + id String @id @default(cuid()) + userId String + title String @db.Text // TODO: Update role, experience, location to use Enums - role String @db.Text - experience String @db.Text - location String @db.Text - url String - additionalInfo String? @db.Text - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - resumesProfile ResumesProfile @relation(fields: [resumesProfileId], references: [id], onDelete: Cascade) - stars ResumesStar[] - comments ResumesComment[] + role String @db.Text + experience String @db.Text + location String @db.Text + url String + additionalInfo String? @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + stars ResumesStar[] + comments ResumesComment[] } model ResumesStar { - id String @id @default(cuid()) - resumesProfileId String - resumeId String - createdAt DateTime @default(now()) - resumesProfile ResumesProfile @relation(fields: [resumesProfileId], references: [id], onDelete: Cascade) - resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade) - - @@unique([resumeId, resumesProfileId]) + id String @id @default(cuid()) + userId String + resumeId String + createdAt DateTime @default(now()) + resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([userId, resumeId]) } model ResumesComment { - id String @id @default(cuid()) - resumesProfileId String - resumeId String - description String @db.Text - section ResumesSection - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - resumesProfile ResumesProfile @relation(fields: [resumesProfileId], references: [id], onDelete: Cascade) - resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade) - votes ResumesCommentVote[] + id String @id @default(cuid()) + userId String + resumeId String + description String @db.Text + section ResumesSection + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade) + votes ResumesCommentVote[] + user User @relation(fields: [userId], references: [id], onDelete: Cascade) } enum ResumesSection { @@ -146,16 +138,16 @@ enum ResumesSection { } model ResumesCommentVote { - id String @id @default(cuid()) - resumesProfileId String - commentId String - value Int - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - resumesProfile ResumesProfile @relation(fields: [resumesProfileId], references: [id], onDelete: Cascade) - comment ResumesComment @relation(fields: [commentId], references: [id], onDelete: Cascade) - - @@unique([commentId, resumesProfileId]) + id String @id @default(cuid()) + userId String + commentId String + value Int + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + comment ResumesComment @relation(fields: [commentId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([userId, commentId]) } // End of Resumes project models. diff --git a/apps/portal/src/pages/resumes/[resumeId].tsx b/apps/portal/src/pages/resumes/[resumeId].tsx index 41a40df4..a9d2b49d 100644 --- a/apps/portal/src/pages/resumes/[resumeId].tsx +++ b/apps/portal/src/pages/resumes/[resumeId].tsx @@ -1,6 +1,9 @@ +import clsx from 'clsx'; import formatDistanceToNow from 'date-fns/formatDistanceToNow'; import Error from 'next/error'; import { useRouter } from 'next/router'; +import { useSession } from 'next-auth/react'; +import { useEffect } from 'react'; import { AcademicCapIcon, BriefcaseIcon, @@ -20,13 +23,42 @@ export default function ResumeReviewPage() { const ErrorPage = ( ); + const { data: session } = useSession(); const router = useRouter(); const { resumeId } = router.query; + const utils = trpc.useContext(); // Safe to assert resumeId type as string because query is only sent if so const detailsQuery = trpc.useQuery( - ['resumes.details.find', { resumeId: resumeId as string }], - { enabled: typeof resumeId === 'string' }, + [ + 'resumes.details.find', + { resumeId: resumeId as string, userId: session?.user?.id }, + ], + { + enabled: typeof resumeId === 'string' && session?.user?.id !== undefined, + }, ); + const starMutation = trpc.useMutation('resumes.details.update_star', { + onSuccess() { + utils.invalidateQueries(); + }, + }); + + useEffect(() => { + if (detailsQuery.data?.stars.length) { + document.getElementById('star-button')?.focus(); + } else { + document.getElementById('star-button')?.blur(); + } + }, [detailsQuery.data?.stars]); + + const onStarButtonClick = () => { + // Star button only rendered if resume exists + // Star button only clickable if user exists + starMutation.mutate({ + resumeId: resumeId as string, + userId: session!.user!.id!, + }); + }; return ( <> @@ -40,11 +72,20 @@ export default function ResumeReviewPage() {