Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 35 additions & 0 deletions .github/workflows/ci-cd-pipline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Deploy Next to Vercel
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
- name: Install dependencies
run: npm install
working-directory: recos
- name: Run tests
run: npm test
working-directory: recos
- name: Build React app
run: npm run build
working-directory: recos
- name: Deploy to Vercel
if: github.ref == 'refs/heads/main'
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: npx vercel --prod --confirm --token $VERCEL_TOKEN
working-directory: recos
2 changes: 1 addition & 1 deletion recos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"start": "next start",
"lint": "eslint",
"test:watch": "jest --watch",
"test": "jest"
"test": "NODE_OPTIONS=--max_old_space_size=4096 jest"
},
"dependencies": {
"@headlessui/react": "^2.2.8",
Expand Down
16 changes: 0 additions & 16 deletions recos/src/app/analytics/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,6 @@ export default function CandidateReportPage() {
timeManagement: 0,
};

const useAIAnalysis = () => ({
analysis,
loading: false,
error: null,
});

const useHiringDecision = (candidateId: string) => ({
decision: null,
isSubmitting: false,
makeDecision: async (value: "reject" | "advance") => {
console.log(`Decision: ${value} for candidate ${candidateId}`);
},
resetDecision: () => {},
error: null,
});

return (
<ClientLayout>
<div className="min-h-screen bg-gray-50">
Expand Down
1 change: 0 additions & 1 deletion recos/src/app/api/companies/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { NextRequest, NextResponse } from 'next/server';

const baseUrl = process.env.BASE_URL;
if (!baseUrl) throw new Error("API base URL missing");

export async function GET(request: NextRequest) {
try {
Expand Down
1 change: 0 additions & 1 deletion recos/src/app/api/odoo-credentials/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { NextRequest, NextResponse } from 'next/server';

const baseUrl = process.env.BASE_URL;
if (!baseUrl) throw new Error("API base URL not configured");

export async function POST(request: NextRequest) {
try {
Expand Down
21 changes: 14 additions & 7 deletions recos/src/app/api/profile/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

const baseUrl = process.env.BASE_URL;
interface ProfileData {
first_name?: string;
last_name?: string;
email?: string;
image?: File | string;
}

export async function GET(request: Request) {
try {
Expand All @@ -9,6 +16,7 @@ export async function GET(request: Request) {
{ status: 401 }
);
}

const response = await fetch(`${baseUrl}/users/`, {
headers: { Authorization: token },
});
Expand Down Expand Up @@ -38,27 +46,26 @@ export async function PATCH(request: Request) {

const contentType = request.headers.get("content-type") || "";

let bodyData: any;
let bodyData: FormData | ProfileData;

if (contentType.includes("multipart/form-data")) {
bodyData = await request.formData();
} else {
const jsonBody = await request.json();
bodyData = JSON.stringify(jsonBody);
bodyData = await request.json() as ProfileData;
}

let headers: { [key: string]: string } = {};
const headers: { [key: string]: string } = {};
if (token) {
headers["Authorization"] = `Token ${token}`;
}
if (!contentType.includes("multipart/form-data")) {
headers["Content-Type"] = contentType;
headers["Content-Type"] = "application/json";
}

const response = await fetch(`${baseUrl}/update-profile/`, {
method: "PATCH",
headers: headers,
body: bodyData,
body: contentType.includes("multipart/form-data") ? bodyData as FormData : JSON.stringify(bodyData as ProfileData),
});

const result = await response.json();
Expand All @@ -70,4 +77,4 @@ export async function PATCH(request: Request) {
{ status: 500 }
);
}
}
}
1 change: 0 additions & 1 deletion recos/src/app/api/verify-odoo/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { NextRequest, NextResponse } from 'next/server';

const baseUrl = process.env.BASE_URL;
if (!baseUrl) throw new Error("API base URL not configured");

export async function POST(request: NextRequest) {
try {
Expand Down
12 changes: 8 additions & 4 deletions recos/src/app/calendar/components/InterviewFormModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React, { useState, useCallback, useEffect, useRef } from "react";
import { CreateInterviewPayload, useCreateInterview } from "@/app/hooks/useCreateInterview";
import { Candidate, Job } from "@/app/types";
import { Candidate, Interview, Job } from "@/app/types";
import { getAllCandidatesForCompany } from "@/app/utils/fetchCandidatesByJobs";
import { fetchJobs } from "@/app/utils/fetchJobs";
import useFetchProfile from "@/app/hooks/useFetchProfile";
Expand All @@ -12,10 +12,14 @@ import { useCompany } from "@/app/context/CompanyContext";
interface InterviewFormModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (data: any) => Promise<void>;
onSave: (data: Interview | CreateInterviewPayload) => Promise<void>;
initialData: CreateInterviewPayload;
scheduledDate?: string;
}
interface Company {
company_id: string;
company_name: string;
}

type CandidateWithJob = Candidate & {
job?: { id?: number; job_title?: string } | number;
Expand Down Expand Up @@ -141,7 +145,7 @@ export default function InterviewFormModal({
setDebugInfo(null);
}, []);

const handleCompanySelect = useCallback((company: any) => {
const handleCompanySelect = useCallback((company: Company) => {
setSelectedCompany(company);
}, [setSelectedCompany]);

Expand Down Expand Up @@ -288,7 +292,7 @@ export default function InterviewFormModal({
onClose();
}, 1500);
} catch (error) {
let errorMessage = "Failed to save interview.";
const errorMessage = "Failed to save interview.";
setError(errorMessage);
} finally {
setSaving(false);
Expand Down
8 changes: 5 additions & 3 deletions recos/src/app/calendar/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import { useToken } from '../hooks/useToken';
import mockRouter from 'next-router-mock';

jest.mock('next/navigation', () => ({
...jest.requireActual('next-router-mock'),
usePathname: () => '/',
useParams: jest.fn(),
usePathname: jest.fn().mockImplementation(() => mockRouter.pathname),
useRouter: jest.fn(() => mockRouter),
useSearchParams: () => new URLSearchParams(),
}));

jest.mock('../hooks/useFetchInterviews');
jest.mock('../hooks/useToken');
jest.mock('./components/Calendar', () => {
return function DummyCalendar(props: any) {
return function DummyCalendar(props: string) {
return <div data-testid="simple-schedule">SimpleSchedule</div>;
};
});
Expand All @@ -25,6 +26,7 @@ describe('CalendarPage', () => {
beforeEach(() => {
mockRouter.setCurrentUrl('/');
mockUseToken.mockReturnValue('fake-token');
(jest.requireMock('next/navigation').useParams as jest.Mock).mockReturnValue({ companyId: '1' });
});

afterEach(() => {
Expand Down
Loading