Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/CuriousCoder00/job-board in…
Browse files Browse the repository at this point in the history
…to feat/company-details-management-page
  • Loading branch information
CuriousCoder00 committed Oct 20, 2024
2 parents a5680bb + 05d6037 commit a4aff9d
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 32 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"start": "next start",
"lint": "next lint",
"dev:docker": "npm run db:seed & next dev",
"db:seed": "npx prisma db push && node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' prisma/seed.ts",
"db:seed": "npx prisma db push && node --loader ts-node/esm prisma/seed.ts",
"db:studio": "npx prisma studio",
"check": "prettier --check \"**/*.{ts,tsx,js,jsx,md,mdx,css}\"",
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,md,mdx,css}\"",
Expand All @@ -31,6 +31,7 @@
"seed": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' prisma/seed.ts"
},
"dependencies": {
"100xdevs-job-board": "file:",
"@aws-sdk/client-s3": "^3.645.0",
"@aws-sdk/s3-request-presigner": "^3.645.0",
"@emotion/react": "^11.13.3",
Expand Down Expand Up @@ -77,6 +78,7 @@
"nextjs-toploader": "^3.7.15",
"node-cron": "^3.0.3",
"nodemailer": "^6.9.15",
"randomstring": "^1.3.0",
"react": "^18",
"react-day-picker": "^8.10.1",
"react-dom": "^18",
Expand All @@ -96,6 +98,7 @@
"@types/node": "^20.16.10",
"@types/node-cron": "^3.0.11",
"@types/nodemailer": "^6.4.16",
"@types/randomstring": "^1.3.0",
"@types/react": "^18",
"@types/react-dom": "^18",
"@typescript-eslint/eslint-plugin": "^8.1.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
-- AlterEnum
ALTER TYPE "Role" ADD VALUE 'HR';

-- DropForeignKey
ALTER TABLE "Job" DROP CONSTRAINT "Job_userId_fkey";
Expand Down
39 changes: 39 additions & 0 deletions prisma/migrations/20241019174425_add_onboar_field/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "onBoard" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "resume" TEXT,
ADD COLUMN "skills" TEXT[];

-- CreateTable
CREATE TABLE "Experience" (
"id" SERIAL NOT NULL,
"companyName" TEXT NOT NULL,
"designation" TEXT NOT NULL,
"EmploymentType" "EmployementType" NOT NULL,
"address" TEXT NOT NULL,
"workMode" "WorkMode" NOT NULL,
"currentWorkStatus" BOOLEAN NOT NULL,
"startDate" TIMESTAMP(3) NOT NULL,
"endDate" TIMESTAMP(3),
"description" TEXT NOT NULL,
"userId" TEXT NOT NULL,

CONSTRAINT "Experience_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Project" (
"id" SERIAL NOT NULL,
"projectName" TEXT NOT NULL,
"projectSummary" TEXT NOT NULL,
"projectLiveLink" TEXT,
"projectGithub" TEXT NOT NULL,
"userId" TEXT NOT NULL,

CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Experience" ADD CONSTRAINT "Experience_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
2 changes: 1 addition & 1 deletion src/app/create-profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function Home() {
if (session.user.onBoard === true) redirect('/jobs');
return (
<div className="flex flex-col justify-center place-items-center">
<h1 className="text-xl font-bold md:text-3xl md:font-extrabold m-auto">
<h1 className="text-xl font-bold md:text-3xl md:font-extrabold mb-8">
Hey {session?.user.name} let&apos;s get you set up and started!
</h1>
<VerticalLinearStepper />
Expand Down
107 changes: 85 additions & 22 deletions src/components/profile/DeleteAccountDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
'use client';

import { useTransition } from 'react';
import { ClipboardEvent, useEffect, useState, useTransition } from 'react';

import { signOut, useSession } from 'next-auth/react';
import { useToast } from '../ui/use-toast';

import { Button } from '../ui/button';
import Loader from '../loader';

import {
Dialog,
Expand All @@ -15,17 +14,43 @@ import {
DialogHeader,
DialogTitle,
DialogTrigger,
DialogClose,
} from '@/components/ui/dialog';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import Randomstring from 'randomstring';
import {
UserProfileDestroySchema,
UserProfileDestroyType,
} from '@/lib/validators/user.profile.validator';

import { deleteUser } from '@/actions/user.profile.actions';
import { Trash } from 'lucide-react';
import { Trash, X } from 'lucide-react';
import { FaSpinner } from 'react-icons/fa';

export const DeleteAccountDialog = () => {
const { toast } = useToast();
const session = useSession();

const {
register,
handleSubmit,
formState: { errors },
} = useForm<UserProfileDestroyType>({
resolver: zodResolver(UserProfileDestroySchema),
});

const [isPending, startTransition] = useTransition();
const [modalOpen, setModalOpen] = useState(false);
const [randomString, setRandomString] = useState<string>('');

const [disabled, setDisabled] = useState(true);

function handleCheck(e: any) {
if (e.target.value === randomString) {
return setDisabled(false);
}
setDisabled(true);
}

const handleDeleteAccount = async () => {
startTransition(() => {
Expand All @@ -46,39 +71,77 @@ export const DeleteAccountDialog = () => {
});
});
};

useEffect(() => {
setRandomString(Randomstring.generate(8));
}, []);

return (
<Dialog>
<Dialog open={modalOpen}>
<DialogTrigger asChild>
<Button className="w-40 flex gap-2 text-red-500" variant={'ghost'}>
<Button
className="w-40 flex gap-2 text-red-500"
variant={'ghost'}
onClick={() => setModalOpen(true)}
>
<Trash size={15} />
Delete Account
</Button>
</DialogTrigger>
<DialogContent>

<DialogContent hideCloseButton>
<div className="flex justify-end">
<X
className="cursor-pointer size-4"
onClick={() => setModalOpen(false)}
/>
</div>
<DialogHeader className="text-start">
<DialogTitle>
Are you sure you want to delete your account?
</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your
account and all associated data.
<form className="mt-6" onSubmit={handleSubmit(handleDeleteAccount)}>
<label className="text-black dark:text-gray-200" htmlFor="random">
Type{' '}
<span className="bg-gray-300 dark:bg-gray-800 text-black dark:text-white font-mono px-2 py-1 rounded">
{randomString}
</span>
</label>
<input
{...register('random')}
id="random"
className=" mt-2 p-2 rounded-md font-bold p-4 rounded-md w-full bg-gray-200 dark:bg-black outline-none text-black dark:text-white"
onPaste={(e: ClipboardEvent<HTMLInputElement>) =>
e.preventDefault()
}
onChange={handleCheck}
/>

{errors.random?.message && (
<p className="mt-2 text-red-500">{errors.random?.message}</p>
)}

<div className="flex gap-2 items-baseline">
<Button
disabled={disabled}
className="mt-4 bg-red-500 hover:bg-red-500 text-white"
>
{isPending ? <FaSpinner className="animate-spin" /> : 'Yes'}
</Button>

<div
className="bg-gray-200 dark:bg-transparent text-black dark:text-white hover:bg-gray-200 hover:dark:bg-transparent border-2 dark:border-slate-500 py-2 px-4 cursor-pointer rounded-md"
onClick={() => setModalOpen(false)}
>
<p>No</p>
</div>
</div>
</form>
</DialogDescription>
</DialogHeader>
<div className="flex gap-4 justify-end">
<Button
className="w-36"
variant={'destructive'}
onClick={handleDeleteAccount}
disabled={isPending}
>
{isPending ? <Loader /> : 'Delete Account'}
</Button>
<DialogClose asChild>
<Button variant={'ghost'} disabled={isPending}>
Cancel
</Button>
</DialogClose>
</div>
</DialogContent>
</Dialog>
);
Expand Down
16 changes: 10 additions & 6 deletions src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
hideCloseButton?: boolean;
}
>(({ className, children, hideCloseButton = false, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
Expand All @@ -44,10 +46,12 @@ const DialogContent = React.forwardRef<
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
{!hideCloseButton && (
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</DialogPortal>
));
Expand Down
9 changes: 9 additions & 0 deletions src/lib/validators/user.profile.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,12 @@ export type projectSchemaType = z.infer<typeof projectSchema>;
export type expFormSchemaType = z.infer<typeof expFormSchema>;
export type addSkillsSchemaType = z.infer<typeof addSkillsSchema>;
export type UserPasswordSchemaType = z.infer<typeof UserPasswordSchema>;

export const UserProfileDestroySchema = z.object({
random: z
.string({ message: 'Required' })
.min(1, { message: 'Min 1 char long' })
.max(8, { message: "Can't be more long" }),
});

export type UserProfileDestroyType = z.infer<typeof UserProfileDestroySchema>;

0 comments on commit a4aff9d

Please sign in to comment.