Skip to content

Commit

Permalink
Feat/admin UI (#553)
Browse files Browse the repository at this point in the history
* fix: deleted jobs were showing

* feat: jobs management page done

* feat: added new ui for the payment and recruiters

* fix: minor changes

* fix:fixed responsiveness

* fix:minor fix

* feat:removed payment

* fix:removed payments

* feat:added filters

* feat:added recruiters

* fix:minor change

* fix:minor changes

* fix:filter fixed

* fix: fixed responsiveness

* fix:minor change
  • Loading branch information
Paribesh01 authored Oct 31, 2024
1 parent 5e66c62 commit 139175f
Show file tree
Hide file tree
Showing 19 changed files with 561 additions and 130 deletions.
19 changes: 15 additions & 4 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,23 @@ model User {
project Project[]
resume String?
oauthProvider OauthProvider? // Tracks OAuth provider (e.g., 'google')
oauthId String?
oauthProvider OauthProvider? // Tracks OAuth provider (e.g., 'google')
oauthId String?
createdAt DateTime @default(now())
blockedByAdmin DateTime?
onBoard Boolean @default(false)
onBoard Boolean @default(false)
bookmark Bookmark[]
companyId String? @unique
company Company? @relation(fields: [companyId], references: [id])
}

model Company {
id String @id @default(cuid())
companyName String
companyLogo String?
companyEmail String
companyBio String
user User?
}

enum OauthProvider {
Expand Down
38 changes: 37 additions & 1 deletion prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,21 @@ const prisma = new PrismaClient();
const users = [
{ id: '1', name: 'Jack', email: '[email protected]' },
{ id: '2', name: 'Admin', email: '[email protected]', role: Role.ADMIN, onBoard: true },
{ id: '3', name: 'Hr', email: '[email protected]', role: Role.HR },
{ id: '3', companyId: '1', name: 'Hr', email: '[email protected]', role: Role.HR, onBoard: true },
{ id: '4', companyId: '2', name: 'John', email: '[email protected]', role: Role.HR, onBoard: true },
{ id: '5', companyId: '3', name: 'Jane', email: '[email protected]', role: Role.HR, onBoard: true },


];


const companies = [
{ id: '1', compnayEmail: "[email protected]", companyName: 'Tech Corp', companyBio: 'Leading tech solutions provider specializing in innovative web development.', companyLogo: '/main.svg' },
{ id: '2', companyEmail: "[email protected]", companyName: 'Global Solutions', companyBio: 'Global Solutions offers comprehensive IT services for businesses worldwide.', companyLogo: '/main.svg' },
{ id: '3', companyEmail: '[email protected]', companyName: 'Innovatech', companyBio: 'Innovatech specializes in backend systems and cloud-based solutions.', companyLogo: '/main.svg' },
]


let jobs = [
{
id: '1',
Expand Down Expand Up @@ -328,6 +340,7 @@ async function seedUsers() {
password: hashedPassword,
role: u.role || Role.USER,
emailVerified: new Date(),
companyId: u.companyId
},
});
console.log(`User created or updated: ${u.email}`);
Expand All @@ -340,6 +353,28 @@ async function seedUsers() {
console.error('Error seeding users:', error);
}
}
async function seedCompanies() {
try {
await Promise.all(
companies.map(async (c) =>
prisma.company.upsert({
where: { id: c.id },
create: {
id: c.id,
companyName: c.companyName,
companyEmail: c.companyEmail ?? "[email protected]",
companyBio: c.companyBio,
companyLogo: c.companyLogo,
},
update: {},
})
)
);
console.log('✅ Company seed completed successfully');
} catch (error) {
console.error('Error seeding companies:', error);
}
}

async function seedJobs() {
try {
Expand Down Expand Up @@ -401,6 +436,7 @@ async function seedJobs() {
}

async function main() {
await seedCompanies();
await seedUsers();
await seedJobs();
}
Expand Down
6 changes: 6 additions & 0 deletions src/actions/job.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export const getAllJobs = withSession<
skills: true,
address: true,
workMode: true,
expired: true,
category: true,
minSalary: true,
maxSalary: true,
Expand Down Expand Up @@ -219,6 +220,7 @@ export const getRecommendedJobs = withServerActionAsyncCatcher<
maxSalary: true,
postedAt: true,
skills: true,
expired: true,
isVerifiedJob: true,
companyLogo: true,
},
Expand Down Expand Up @@ -252,6 +254,7 @@ export const getRecommendedJobs = withServerActionAsyncCatcher<
companyLogo: true,
minExperience: true,
maxExperience: true,
expired: true,
isVerifiedJob: true,
category: true,
},
Expand Down Expand Up @@ -294,6 +297,7 @@ export const getJobById = withServerActionAsyncCatcher<
minExperience: true,
maxExperience: true,
skills: true,
expired: true,
address: true,
workMode: true,
hasSalaryRange: true,
Expand Down Expand Up @@ -352,6 +356,7 @@ export const getRecentJobs = async () => {
minExperience: true,
maxExperience: true,
skills: true,
expired: true,
postedAt: true,
companyLogo: true,
type: true,
Expand Down Expand Up @@ -601,6 +606,7 @@ export async function GetBookmarkByUserId() {
minSalary: true,
maxSalary: true,
postedAt: true,
expired: true,
companyLogo: true,
},
},
Expand Down
36 changes: 36 additions & 0 deletions src/actions/user.profile.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,39 @@ export const getUserDetails = async () => {
return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
}
};

export const getUserRecruiters = async () => {
const auth = await getServerSession(authOptions);

if (!auth || !auth?.user?.id || auth?.user?.role !== 'ADMIN')
throw new ErrorHandler('Not Authorized', 'UNAUTHORIZED');
try {
const res = await prisma.user.findMany({
where: {
role: 'HR',
},
select: {
id: true,
email: true,
name: true,
createdAt: true,
_count: {
select: {
jobs: true,
},
},
company: {
select: {
companyName: true,
companyEmail: true,
},
},
},
});
return new SuccessResponse('Recruiter SuccessFully Fetched', 200, {
recruiters: res,
}).serialize();
} catch (_error) {
return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
}
};
6 changes: 1 addition & 5 deletions src/app/manage/page.tsx → src/app/manage/jobs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ const ManageJob = async ({
redirect('/jobs');
}
const searchParamss = parsedData.data;
return (
<div className="container">
<JobManagement searchParams={searchParamss} />
</div>
);
return <JobManagement searchParams={searchParamss} />;
};

export default ManageJob;
22 changes: 22 additions & 0 deletions src/app/manage/recruiters/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getUserRecruiters } from '@/actions/user.profile.actions';
import ManageRecruiters from '@/components/ManageRecruiters';

import { options } from '@/lib/auth';
import { getServerSession } from 'next-auth';
import { redirect } from 'next/navigation';
import React from 'react';

const RecruitersPage = async () => {
const server = await getServerSession(options);
if (!server?.user) {
redirect('/api/auth/signin');
} else if (server.user.role !== 'ADMIN') {
redirect('/jobs');
}

const Recruiters = await getUserRecruiters();

return <ManageRecruiters recruiters={Recruiters} />;
};

export default RecruitersPage;
10 changes: 7 additions & 3 deletions src/components/DeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Button } from './ui/button';
import { useToast } from './ui/use-toast';
import { toggleDeleteJobById } from '@/actions/job.action';
import { JobType } from '@/types/jobs.types';
import icons from '@/lib/icons';
import {
Dialog,
DialogTrigger,
Expand All @@ -13,7 +14,6 @@ import {
DialogDescription,
DialogFooter,
} from './ui/dialog';
import { ArchiveRestore, Trash } from 'lucide-react';

const JobDialog = ({ job }: { job: JobType }) => {
const [dialogOpen, setDialogOpen] = useState(false); // State to manage dialog visibility
Expand Down Expand Up @@ -42,15 +42,19 @@ const JobDialog = ({ job }: { job: JobType }) => {
role="button"
onClick={() => setDialogOpen(true)}
>
<ArchiveRestore /> {/* Icon for restoring the job */}
<Button variant="ghost" size="icon">
<icons.ArchiveRestore className="h-7 w-5 text-green-500" />
</Button>
</span>
) : (
<span
className="mr-5"
role="button"
onClick={() => setDialogOpen(true)}
>
<Trash /> {/* Icon for deleting the job */}
<Button variant="ghost" size="icon">
<icons.trash className="h-7 w-5 text-red-500" />
</Button>
</span>
)}
</DialogTrigger>
Expand Down
7 changes: 3 additions & 4 deletions src/components/JobManagement.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { getAllJobs } from '@/actions/job.action';
import JobManagementHeader from './JobManagementHeader';
import JobManagementTable from './JobManagementTable';
import { JobQuerySchemaType } from '@/lib/validators/jobs.validator';

Expand All @@ -13,10 +12,10 @@ const JobManagement = async ({
if (!jobs.status) {
return <div>Error {jobs.message}</div>;
}

return (
<div className="pt-2 px-6 mt-10">
<JobManagementHeader />
<JobManagementTable jobs={jobs} searchParams={searchParams} />
<div>
<JobManagementTable jobs={jobs.additional} searchParams={searchParams} />
</div>
);
};
Expand Down
Loading

0 comments on commit 139175f

Please sign in to comment.