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
33 changes: 33 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Dependencies
node_modules
npm-debug.log*

# Environment variables
.env*

# IDE files
.vscode
.idea

# OS files
.DS_Store
Thumbs.db

# Git
.git
.gitignore

# Docker
Dockerfile
.dockerignore

# Logs
logs
*.log

# Coverage
coverage

# Temporary files
tmp
temp
36 changes: 36 additions & 0 deletions .github/workflows/build-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Build & lint workflow
on: [push, pull_request]
run-name: Workflow created by ${{github.actor}} on ${{github.event_name}} event

jobs:
check_lint_and_build:
runs-on: ubuntu-latest
steps:
- name: action checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "20"
cache: "npm"
cache-dependency-path: |
backend/package-lock.json
frontend/package-lock.json

- name: check lint in backend
working-directory: backend
run: |
npm install
npm run lint --max-warnings=0
echo ::notice::Backend linting passed

- name: check lint and build in frontend
working-directory: frontend
run: |
npm install
npm run lint --max-warnings=0
npm run build
echo ::notice::Frontend linting and build passed
20 changes: 20 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM node:20-alpine

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm ci

RUN mkdir -p public/uploads

COPY backend ./

EXPOSE 3000

# Start the backend server
CMD ["npm", "run", "dev"]


# Build image with:
#docker build -t careerly-backend-image -f backend/Dockerfile .
1 change: 0 additions & 1 deletion backend/controllers/authControllers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const { StatusCodes } = require("http-status-codes");
const Job = require("../models/JobModel");
const User = require("../models/UserModel");
const generateCookie = require("../utils/generateCookie");

Expand Down
3 changes: 3 additions & 0 deletions backend/data/populate.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* eslint-env node */
/* global process */

const mockData = require("./mockData");
const Job = require("../models/JobModel");
require("dotenv").config();
Expand Down
6 changes: 4 additions & 2 deletions backend/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-env node */
/* global process, __dirname, */
const express = require("express");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
Expand Down Expand Up @@ -29,8 +31,8 @@ app.use("/api/v1/jobs", jobsRouter);
app.use("/api/v1/auth", authRouter);
app.use("/api/v1/users", userRouter);

app.use((err, req, res, next) => {
console.log(chalk.red(err));
app.use((err, req, res) => {
console.log(err);
res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json({ msg: `Error: ${err.message}` });
Expand Down
4 changes: 3 additions & 1 deletion backend/middlewares/authMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* global process */

const { StatusCodes } = require("http-status-codes");
const jwt = require("jsonwebtoken");
const User = require("../models/UserModel");
Expand All @@ -15,7 +17,7 @@ const protect = async (req, res, next) => {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;

isTestUser = req.user.userId === "684214b2e2b9a4904b708c9b";
const isTestUser = req.user.userId === "684214b2e2b9a4904b708c9b";
const activeUser = await User.findById(req.user.userId).select("-password");
if (!activeUser) {
return res
Expand Down
2 changes: 2 additions & 0 deletions backend/utils/generateCookie.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* global process*/

const jwt = require("jsonwebtoken");

const generateCookie = (user, res) => {
Expand Down
36 changes: 36 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "5174:5173"
volumes:
- ./frontend:/app
- frontend-node-modules:/app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true

depends_on:
- backend

restart: unless-stopped

backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "3001:3000"
volumes:
- ./backend:/app
- backend-node-node_modules:/app/node_modules
environment:
- NODE_ENV=development
env_file:
- .env
restart: unless-stopped

volumes:
backend-node-modules:
frontend-node-modules:
8 changes: 8 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import js from "@eslint/js";
import globals from "globals";
import { defineConfig } from "eslint/config";

export default defineConfig([
{ files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: globals.browser } },
{ files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } },
]);
18 changes: 18 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:20-alpine

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm ci

COPY . ./

EXPOSE 5173


CMD ["npm", "run", "dev", "--", "--host"]


# Build image with:
#docker build -t careerly-frontend-image .
4 changes: 2 additions & 2 deletions frontend/src/components/BigSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import styled from "styled-components";
import { Link } from "react-router";
import { FiPlusCircle, FiList, FiBarChart2, FiUser } from "react-icons/fi";
import { LuLogOut } from "react-icons/lu";
import { useDashboardContext } from "../pages/DashboardLayout";
import { useDashboardContext } from "../hooks/useDashboardContext";

const BigSidebar = () => {
const { user, setIsSidebarOpen } = useDashboardContext();
const { setIsSidebarOpen } = useDashboardContext();
return (
<Wrapper onClick={() => setIsSidebarOpen(false)}>
<div
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Burger.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import styled from "styled-components";
import { useDashboardContext } from "../pages/DashboardLayout";
import { useDashboardContext } from "../hooks/useDashboardContext";

const Burger = () => {
const { isSidebarOpen, setIsSidebarOpen } = useDashboardContext();
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Switch from "./Switch";
import styled from "styled-components";
import img from "../assets/images/user-pic.jpg";
import Burger from "./Burger";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";

const Navbar = () => {
const { data: user } = useQuery({
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Switch.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import styled from "styled-components";
import { useDashboardContext } from "../pages/DashboardLayout";
import { useDashboardContext } from "../hooks/useDashboardContext";

const Switch = () => {
const { toggleDarkTheme, isDarkTheme } = useDashboardContext();
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/contexts/DashboardContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from "react";

const DashboardContext = createContext();

export default DashboardContext;
6 changes: 6 additions & 0 deletions frontend/src/hooks/useDashboardContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useContext } from "react";
import DashboardContext from "../contexts/DashboardContext";

export const useDashboardContext = () => {
return useContext(DashboardContext);
};
2 changes: 1 addition & 1 deletion frontend/src/pages/AllJobs.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import styled from "styled-components";
import {
Expand Down
9 changes: 2 additions & 7 deletions frontend/src/pages/DashboardLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import React from "react";
import Navbar from "../components/Navbar";
import { Outlet } from "react-router";
import Sidebar from "../components/Sidebar";
import { useState, createContext, useContext } from "react";
import { useState } from "react";
import BigSidebar from "../components/BigSidebar";
import styled from "styled-components";

const DashboardContext = createContext();
import DashboardContext from "../contexts/DashboardContext";
const DashboardLayout = ({ currentTheme }) => {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const user = {
Expand Down Expand Up @@ -52,8 +51,4 @@ const Wrapper = styled.div`
}
`;

export const useDashboardContext = () => {
return useContext(DashboardContext);
};

export default DashboardLayout;
7 changes: 3 additions & 4 deletions frontend/src/pages/Stats.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import axiosInstance from "../utils/axios";
import DoughnutChart from "../components/DoughnutChart";
import LineChart from "../components/LineChart";
import styled from "styled-components";

const Stats = () => {
const queryClient = useQueryClient();
const { data, isLoading } = useQuery({
const { data } = useQuery({
queryKey: ["chartData"],
queryFn: async () => {
const response = await axiosInstance.get("/users/stats");
Expand All @@ -16,7 +15,7 @@ const Stats = () => {
});

const { defaultStats, monthlyApplications } = data || {};
console.log(data);

return (
<Wrapper>
<div className="chart-container">
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon backend/index.js",
"setup-project": "npm i && cd frontend && npm i"
"setup-project": "npm i && cd frontend && npm i",
"lint": "eslint backend"
},
"author": "",
"license": "ISC",
Expand All @@ -29,6 +30,9 @@
"nanoid": "^5.1.5"
},
"devDependencies": {
"@eslint/js": "^9.36.0",
"eslint": "^9.36.0",
"globals": "^16.4.0",
"nodemon": "^3.1.10"
}
}
Loading