Skip to content

Commit 44bc883

Browse files
Merge pull request #15 from akirachix/feature/ci-cd
Feature/ci cd
2 parents 5bdbe1a + 840498f commit 44bc883

File tree

29 files changed

+662
-277
lines changed

29 files changed

+662
-277
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Deploy Next to Vercel
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- develop
7+
pull_request:
8+
branches:
9+
- main
10+
- develop
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v3
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v3
19+
with:
20+
node-version: "18"
21+
- name: Install dependencies
22+
run: npm install
23+
working-directory: recos
24+
- name: Run tests
25+
run: npm test
26+
working-directory: recos
27+
- name: Build React app
28+
run: npm run build
29+
working-directory: recos
30+
- name: Deploy to Vercel
31+
if: github.ref == 'refs/heads/main'
32+
env:
33+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
34+
run: npx vercel --prod --confirm --token $VERCEL_TOKEN
35+
working-directory: recos

recos/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"start": "next start",
99
"lint": "eslint",
1010
"test:watch": "jest --watch",
11-
"test": "jest"
11+
"test": "NODE_OPTIONS=--max_old_space_size=4096 jest"
1212
},
1313
"dependencies": {
1414
"@headlessui/react": "^2.2.8",

recos/src/app/analytics/page.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,6 @@ export default function CandidateReportPage() {
6767
timeManagement: 0,
6868
};
6969

70-
const useAIAnalysis = () => ({
71-
analysis,
72-
loading: false,
73-
error: null,
74-
});
75-
76-
const useHiringDecision = (candidateId: string) => ({
77-
decision: null,
78-
isSubmitting: false,
79-
makeDecision: async (value: "reject" | "advance") => {
80-
console.log(`Decision: ${value} for candidate ${candidateId}`);
81-
},
82-
resetDecision: () => {},
83-
error: null,
84-
});
85-
8670
return (
8771
<ClientLayout>
8872
<div className="min-h-screen bg-gray-50">

recos/src/app/api/companies/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server';
22

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

65
export async function GET(request: NextRequest) {
76
try {

recos/src/app/api/odoo-credentials/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server';
22

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

65
export async function POST(request: NextRequest) {
76
try {

recos/src/app/api/profile/route.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
12
const baseUrl = process.env.BASE_URL;
3+
interface ProfileData {
4+
first_name?: string;
5+
last_name?: string;
6+
email?: string;
7+
image?: File | string;
8+
}
29

310
export async function GET(request: Request) {
411
try {
@@ -9,6 +16,7 @@ export async function GET(request: Request) {
916
{ status: 401 }
1017
);
1118
}
19+
1220
const response = await fetch(`${baseUrl}/users/`, {
1321
headers: { Authorization: token },
1422
});
@@ -38,27 +46,26 @@ export async function PATCH(request: Request) {
3846

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

41-
let bodyData: any;
49+
let bodyData: FormData | ProfileData;
4250

4351
if (contentType.includes("multipart/form-data")) {
4452
bodyData = await request.formData();
4553
} else {
46-
const jsonBody = await request.json();
47-
bodyData = JSON.stringify(jsonBody);
54+
bodyData = await request.json() as ProfileData;
4855
}
4956

50-
let headers: { [key: string]: string } = {};
57+
const headers: { [key: string]: string } = {};
5158
if (token) {
5259
headers["Authorization"] = `Token ${token}`;
5360
}
5461
if (!contentType.includes("multipart/form-data")) {
55-
headers["Content-Type"] = contentType;
62+
headers["Content-Type"] = "application/json";
5663
}
5764

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

6471
const result = await response.json();
@@ -70,4 +77,4 @@ export async function PATCH(request: Request) {
7077
{ status: 500 }
7178
);
7279
}
73-
}
80+
}

recos/src/app/api/verify-odoo/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server';
22

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

65
export async function POST(request: NextRequest) {
76
try {

recos/src/app/calendar/components/InterviewFormModal/index.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import React, { useState, useCallback, useEffect, useRef } from "react";
44
import { CreateInterviewPayload, useCreateInterview } from "@/app/hooks/useCreateInterview";
5-
import { Candidate, Job } from "@/app/types";
5+
import { Candidate, Interview, Job } from "@/app/types";
66
import { getAllCandidatesForCompany } from "@/app/utils/fetchCandidatesByJobs";
77
import { fetchJobs } from "@/app/utils/fetchJobs";
88
import useFetchProfile from "@/app/hooks/useFetchProfile";
@@ -12,10 +12,14 @@ import { useCompany } from "@/app/context/CompanyContext";
1212
interface InterviewFormModalProps {
1313
isOpen: boolean;
1414
onClose: () => void;
15-
onSave: (data: any) => Promise<void>;
15+
onSave: (data: Interview | CreateInterviewPayload) => Promise<void>;
1616
initialData: CreateInterviewPayload;
1717
scheduledDate?: string;
1818
}
19+
interface Company {
20+
company_id: string;
21+
company_name: string;
22+
}
1923

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

144-
const handleCompanySelect = useCallback((company: any) => {
148+
const handleCompanySelect = useCallback((company: Company) => {
145149
setSelectedCompany(company);
146150
}, [setSelectedCompany]);
147151

@@ -288,7 +292,7 @@ export default function InterviewFormModal({
288292
onClose();
289293
}, 1500);
290294
} catch (error) {
291-
let errorMessage = "Failed to save interview.";
295+
const errorMessage = "Failed to save interview.";
292296
setError(errorMessage);
293297
} finally {
294298
setSaving(false);

recos/src/app/calendar/page.test.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ import { useToken } from '../hooks/useToken';
55
import mockRouter from 'next-router-mock';
66

77
jest.mock('next/navigation', () => ({
8-
...jest.requireActual('next-router-mock'),
9-
usePathname: () => '/',
8+
useParams: jest.fn(),
9+
usePathname: jest.fn().mockImplementation(() => mockRouter.pathname),
10+
useRouter: jest.fn(() => mockRouter),
1011
useSearchParams: () => new URLSearchParams(),
1112
}));
1213

1314
jest.mock('../hooks/useFetchInterviews');
1415
jest.mock('../hooks/useToken');
1516
jest.mock('./components/Calendar', () => {
16-
return function DummyCalendar(props: any) {
17+
return function DummyCalendar(props: string) {
1718
return <div data-testid="simple-schedule">SimpleSchedule</div>;
1819
};
1920
});
@@ -25,6 +26,7 @@ describe('CalendarPage', () => {
2526
beforeEach(() => {
2627
mockRouter.setCurrentUrl('/');
2728
mockUseToken.mockReturnValue('fake-token');
29+
(jest.requireMock('next/navigation').useParams as jest.Mock).mockReturnValue({ companyId: '1' });
2830
});
2931

3032
afterEach(() => {

0 commit comments

Comments
 (0)