Skip to content

Commit e107104

Browse files
Merge pull request #14 from Sachinchaurasiya360/feature/ai-job-match
Feature/ai job match
2 parents c94d271 + 6187b82 commit e107104

45 files changed

Lines changed: 3687 additions & 223 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

client/src/App.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ const CompliancePage = lazyWithRetry(() => import("./module/recruiter/hr/Complia
171171
const WorkflowsPage = lazyWithRetry(() => import("./module/recruiter/hr/WorkflowsPage"));
172172
const RolesPage = lazyWithRetry(() => import("./module/recruiter/hr/RolesPage"));
173173

174+
// InternHack AI pages
175+
const JobAgentPage = lazyWithRetry(() => import("./module/student/job-agent/JobAgentPage"));
176+
174177
// Student new feature pages
175178
const CampusDrivesPage = lazyWithRetry(() => import("./module/student/campus/CampusDrivesPage"));
176179
const CampusDriveDetailPage = lazyWithRetry(() => import("./module/student/campus/CampusDriveDetailPage"));
@@ -182,7 +185,7 @@ const AdminDashboard = lazyWithRetry(() => import("./module/admin/AdminDashboard
182185
const UsersListPage = lazyWithRetry(() => import("./module/admin/users/UsersListPage"));
183186
const UserDetailPage = lazyWithRetry(() => import("./module/admin/users/UserDetailPage"));
184187
const AdminJobsListPage = lazyWithRetry(() => import("./module/admin/jobs/AdminJobsListPage"));
185-
const ActivityLogsPage = lazyWithRetry(() => import("./module/admin/activity/ActivityLogsPage"));
188+
const ErrorLogsPage = lazyWithRetry(() => import("./module/admin/activity/ActivityLogsPage"));
186189
const AdminCompaniesPage = lazyWithRetry(() => import("./module/admin/companies/AdminCompaniesPage"));
187190
const AdminReviewsPage = lazyWithRetry(() => import("./module/admin/reviews/AdminReviewsPage"));
188191
const AdminContributionsPage = lazyWithRetry(() => import("./module/admin/contributions/AdminContributionsPage"));
@@ -372,7 +375,8 @@ function App() {
372375
<Route path="opensource/gsoc-proposal" element={<GSoCProposalPage />} />
373376
<Route path="opensource/gsoc-proposal/:sectionSlug" element={<GSoCProposalStepPage />} />
374377
<Route path="opensource/analytics" element={<OpenSourceAnalyticsPage />} />
375-
<Route path="campus-drives" element={<CampusDrivesPage />} />
378+
<Route path="ai-agent" element={<JobAgentPage />} />
379+
<Route path="campus-drives" element={<CampusDrivesPage />} />
376380
<Route path="campus-drives/:id" element={<CampusDriveDetailPage />} />
377381
<Route path="checkout" element={<CheckoutPage />} />
378382
<Route path="profile" element={<StudentProfilePage />} />
@@ -425,7 +429,7 @@ function App() {
425429
<Route path="users" element={<UsersListPage />} />
426430
<Route path="users/:id" element={<UserDetailPage />} />
427431
<Route path="jobs" element={<AdminJobsListPage />} />
428-
<Route path="activity" element={<ActivityLogsPage />} />
432+
<Route path="errors" element={<ErrorLogsPage />} />
429433
<Route path="companies" element={<AdminCompaniesPage />} />
430434
<Route path="reviews" element={<AdminReviewsPage />} />
431435
<Route path="contributions" element={<AdminContributionsPage />} />
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Link } from "react-router";
2+
import { Crown, Sparkles, Zap, MessageCircle } from "lucide-react";
3+
4+
interface Props {
5+
feature: string;
6+
}
7+
8+
export function PremiumUpgradeCTA({ feature }: Props) {
9+
return (
10+
<div className="flex items-center justify-center min-h-[60vh] px-6">
11+
<div className="max-w-md w-full text-center">
12+
<div className="w-16 h-16 rounded-2xl bg-indigo-50 dark:bg-indigo-900/20 flex items-center justify-center mx-auto mb-6">
13+
<Sparkles className="w-8 h-8 text-indigo-600 dark:text-indigo-400" />
14+
</div>
15+
<h2 className="text-2xl font-bold text-gray-950 dark:text-white mb-2">
16+
Unlock {feature}
17+
</h2>
18+
<p className="text-gray-500 dark:text-gray-400 mb-8">
19+
Upgrade to Premium to access AI-powered job recommendations, smart matching, and conversational job discovery.
20+
</p>
21+
<div className="space-y-3 text-left mb-8">
22+
{[
23+
{ icon: Zap, text: "Personalized job feed ranked by AI" },
24+
{ icon: MessageCircle, text: "Chat with InternHack AI to find jobs" },
25+
{ icon: Crown, text: "50 AI conversations per day" },
26+
].map(({ icon: Icon, text }) => (
27+
<div key={text} className="flex items-center gap-3 text-sm text-gray-700 dark:text-gray-300">
28+
<Icon className="w-4 h-4 text-indigo-500 shrink-0" />
29+
<span>{text}</span>
30+
</div>
31+
))}
32+
</div>
33+
<Link
34+
to="/student/checkout"
35+
className="inline-flex items-center gap-2 px-6 py-3 bg-gray-950 dark:bg-white text-white dark:text-gray-950 text-sm font-semibold rounded-xl hover:bg-gray-800 dark:hover:bg-gray-200 transition-colors no-underline"
36+
>
37+
<Crown className="w-4 h-4" />
38+
Upgrade to Premium
39+
</Link>
40+
</div>
41+
</div>
42+
);
43+
}

client/src/components/StudentSidebar.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { useState } from "react";
22
import { NavLink, Link, useNavigate } from "react-router";
3-
import { Briefcase, FileText, LogOut, ScanSearch, Building2, ChevronsLeft, ChevronsRight, UserCircle, Award, Globe, Crown, ShieldCheck, Video, GraduationCap, User, Menu, X, Sun, Moon, Lock } from "lucide-react";
3+
import { Briefcase, FileText, LogOut, ScanSearch, Building2, ChevronsLeft, ChevronsRight, UserCircle, Award, Globe, Crown, ShieldCheck, Video, GraduationCap, User, Menu, X, Sun, Moon, Lock, BrainCircuit } from "lucide-react";
44
import { useAuthStore } from "../lib/auth.store";
55
import { useThemeStore } from "../lib/theme.store";
66

77
const NAV_ITEMS = [
88
{ to: "/student/jobs", icon: Briefcase, label: "Browse Jobs" },
9+
{ to: "/student/ai-agent", icon: BrainCircuit, label: "InternHack AI" },
910
{ to: "/student/applications", icon: FileText, label: "My Applications" },
1011
{ to: "/student/ats/score", icon: ScanSearch, label: "Resume" },
1112
{ to: "/learn", icon: GraduationCap, label: "Learning Hub" },

client/src/lib/query-keys.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export const queryKeys = {
4444
subscribers: () => ["admin", "subscribers"] as const,
4545
aiConfig: () => ["admin", "ai-config"] as const,
4646
aiStats: (range: string) => ["admin", "ai-stats", range] as const,
47+
errorLogs: (params?: Record<string, string | number>) =>
48+
["admin", "error-logs", params] as const,
4749
},
4850

4951
// Profile
@@ -173,6 +175,17 @@ export const queryKeys = {
173175
detail: (id: number) => ["email-campaigns", "detail", id] as const,
174176
},
175177

178+
// Job Feed (InternHack AI)
179+
jobFeed: {
180+
feed: (page: number) => ["job-feed", "feed", page] as const,
181+
preferences: () => ["job-feed", "preferences"] as const,
182+
saved: () => ["job-feed", "saved"] as const,
183+
stats: () => ["job-feed", "stats"] as const,
184+
},
185+
jobAgent: {
186+
conversation: () => ["job-agent", "conversation"] as const,
187+
},
188+
176189
// DSA Practice
177190
dsa: {
178191
topics: (filter?: string) => ["dsa", "topics", filter] as const,

client/src/lib/types.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,19 @@ export interface ActivityLog {
395395
createdAt: string;
396396
}
397397

398+
export interface ErrorLog {
399+
id: number;
400+
method: string;
401+
path: string;
402+
statusCode: number;
403+
message: string;
404+
userId: number | null;
405+
ipAddress: string | null;
406+
userAgent: string | null;
407+
requestBody: Record<string, unknown> | null;
408+
createdAt: string;
409+
}
410+
398411
// Talent Search
399412
export interface TalentSearchResult {
400413
id: number;
@@ -1036,3 +1049,57 @@ export interface ChatMessage {
10361049
content: string;
10371050
}
10381051

1052+
// ── InternHack AI Types ──
1053+
1054+
export interface JobFeedMatch {
1055+
matchId: number;
1056+
score: number;
1057+
skillMatch: number;
1058+
locationMatch: number;
1059+
salaryMatch: number;
1060+
saved: boolean;
1061+
seen: boolean;
1062+
job: {
1063+
id: number;
1064+
title: string;
1065+
company: string;
1066+
location: string;
1067+
salary: string | null;
1068+
skills: string[];
1069+
workMode: string | null;
1070+
experienceLevel: string | null;
1071+
applicationUrl: string | null;
1072+
tags: string[];
1073+
createdAt: string;
1074+
};
1075+
}
1076+
1077+
export interface JobPreferences {
1078+
desiredRoles: string[];
1079+
desiredSkills: string[];
1080+
desiredLocations: string[];
1081+
minSalary: number | null;
1082+
workMode: string[];
1083+
experienceLevel: string[];
1084+
domains: string[];
1085+
}
1086+
1087+
export interface JobAgentMessage {
1088+
role: "user" | "assistant";
1089+
content: string;
1090+
timestamp: string;
1091+
jobCount?: number;
1092+
}
1093+
1094+
export interface JobAgentResponse {
1095+
reply: string;
1096+
jobs: JobFeedMatch["job"][];
1097+
preferencesUpdated: boolean;
1098+
}
1099+
1100+
export interface JobFeedStats {
1101+
total: number;
1102+
unseen: number;
1103+
saved: number;
1104+
}
1105+

client/src/module/admin/AdminLayout.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState } from "react";
22
import { NavLink, Outlet } from "react-router";
3-
import { LayoutDashboard, Users, Briefcase, ScrollText, Shield, LogOut, Building2, MessageSquare, GitPullRequest, Mail, BookOpen, Code2, Brain, BadgeCheck, Trophy, Award, Cpu, ExternalLink, Menu, X } from "lucide-react";
3+
import { LayoutDashboard, Users, Briefcase, AlertTriangle, Shield, LogOut, Building2, MessageSquare, GitPullRequest, Mail, BookOpen, Code2, Brain, BadgeCheck, Trophy, Award, Cpu, ExternalLink, Menu, X } from "lucide-react";
44
import { useAuthStore } from "../../lib/auth.store";
55
import { useNavigate } from "react-router";
66
import { SEO } from "../../components/SEO";
@@ -51,9 +51,9 @@ export default function AdminLayout() {
5151
<Briefcase className="w-4 h-4" />
5252
Jobs
5353
</NavLink>
54-
<NavLink to="/admin/activity" className={linkClass} onClick={() => setSidebarOpen(false)}>
55-
<ScrollText className="w-4 h-4" />
56-
Activity Logs
54+
<NavLink to="/admin/errors" className={linkClass} onClick={() => setSidebarOpen(false)}>
55+
<AlertTriangle className="w-4 h-4" />
56+
Error Logs
5757
</NavLink>
5858
<NavLink to="/admin/companies" className={linkClass} onClick={() => setSidebarOpen(false)}>
5959
<Building2 className="w-4 h-4" />

0 commit comments

Comments
 (0)