Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
2023-24-088
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Rishad M.H.M
2023-24-088
Commits
f4129b48
Commit
f4129b48
authored
Nov 26, 2023
by
IT20613686
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Job posting endpoint and integration
parent
9a21a2a1
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
471 additions
and
31 deletions
+471
-31
BACKEND/models/job.js
BACKEND/models/job.js
+61
-0
BACKEND/routes/jobs.js
BACKEND/routes/jobs.js
+65
-0
BACKEND/server.js
BACKEND/server.js
+2
-4
frontend/package-lock.json
frontend/package-lock.json
+198
-0
frontend/package.json
frontend/package.json
+4
-0
frontend/src/Component/Job Posting/JobPosting.js
frontend/src/Component/Job Posting/JobPosting.js
+141
-27
No files found.
BACKEND/models/job.js
0 → 100644
View file @
f4129b48
const
mongoose
=
require
(
"
mongoose
"
);
const
Schema
=
mongoose
.
Schema
;
const
jobSchema
=
new
Schema
({
jobID
:
{
type
:
String
,
},
title
:
{
type
:
String
,
required
:
true
,
},
company
:
{
type
:
String
,
required
:
true
,
},
location
:
{
type
:
String
,
required
:
true
,
},
workType
:
{
type
:
String
,
required
:
true
,
},
term
:
{
type
:
String
,
required
:
true
,
},
salary
:
{
type
:
Number
,
required
:
true
,
},
duration
:
{
type
:
String
,
required
:
true
,
},
deadline
:
{
type
:
Date
,
required
:
true
,
},
logo
:
{
type
:
String
,
required
:
true
,
},
responsibilities
:
{
type
:
String
,
required
:
true
,
},
qualifications
:
{
type
:
String
,
required
:
true
,
},
aboutJob
:
{
type
:
String
,
required
:
true
,
},
});
const
Job
=
mongoose
.
model
(
"
Job
"
,
jobSchema
);
module
.
exports
=
Job
;
BACKEND/routes/jobs.js
0 → 100644
View file @
f4129b48
const
router
=
require
(
"
express
"
).
Router
();
const
multer
=
require
(
"
multer
"
);
let
Job
=
require
(
"
../models/job
"
);
const
storage
=
multer
.
diskStorage
({
destination
:
(
req
,
file
,
cb
)
=>
{
cb
(
null
,
"
uploads
"
);
},
filename
:
(
req
,
file
,
cb
)
=>
{
cb
(
null
,
Date
.
now
()
+
file
.
originalname
);
},
});
const
upload
=
multer
({
storage
:
storage
,
}).
single
(
"
logo
"
);
router
.
post
(
"
/add
"
,
upload
,
async
(
req
,
res
)
=>
{
const
newJob
=
new
Job
({
jobID
:
req
.
body
,
title
:
req
.
body
.
title
,
company
:
req
.
body
.
company
,
location
:
req
.
body
.
location
,
workType
:
req
.
body
.
workType
,
term
:
req
.
body
.
term
,
salary
:
req
.
body
.
salary
,
duration
:
req
.
body
.
duration
,
deadline
:
req
.
body
.
deadline
,
logo
:
req
.
file
.
filename
,
responsibilities
:
req
.
body
.
responsibilities
,
qualifications
:
req
.
body
.
qualifications
,
aboutJob
:
req
.
body
.
aboutJob
,
});
const
totalNumberOfJobInDb
=
await
Job
.
countDocuments
();
// convert number to string, so we can concatenate 0s easily...
let
numberToString
=
totalNumberOfJobInDb
.
toString
();
// If length of number string is less than 5 then add leading 0s in nuberToString
if
(
numberToString
.
length
<
3
)
{
for
(
let
i
=
numberToString
.
length
;
i
<
3
;
i
++
)
{
numberToString
=
"
0
"
+
numberToString
;
}
}
newJob
.
jobID
=
`JID
${
numberToString
}
`
;
newJob
.
save
()
.
then
(()
=>
{
res
.
status
(
200
).
send
({
status
:
"
Job added
"
});
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
res
.
status
(
500
)
.
send
({
status
:
"
Error with adding job
"
,
error
:
err
.
message
});
});
});
module
.
exports
=
router
;
\ No newline at end of file
BACKEND/server.js
View file @
f4129b48
...
@@ -5,8 +5,7 @@ const cors = require("cors");
...
@@ -5,8 +5,7 @@ const cors = require("cors");
const
connectDB
=
require
(
"
./config/db
"
);
const
connectDB
=
require
(
"
./config/db
"
);
const
dotenv
=
require
(
"
dotenv
"
);
const
dotenv
=
require
(
"
dotenv
"
);
const
userRoutes
=
require
(
"
./routes/userRoutes
"
);
const
userRoutes
=
require
(
"
./routes/userRoutes
"
);
// const hardwareRouter = require("./routes/hardwares.js");
const
jobRoutes
=
require
(
"
./routes/jobs
"
)
// const hardwareItemRouter = require("./routes/hardwareItems.js");
const
{
notFound
,
errorHandler
}
=
require
(
"
./middlewares/errorMiddleware
"
);
const
{
notFound
,
errorHandler
}
=
require
(
"
./middlewares/errorMiddleware
"
);
const
app
=
express
();
const
app
=
express
();
...
@@ -21,8 +20,7 @@ app.use(bodyparser.urlencoded({ extended: true }));
...
@@ -21,8 +20,7 @@ app.use(bodyparser.urlencoded({ extended: true }));
app
.
use
(
'
/uploads
'
,
express
.
static
(
'
./uploads
'
));
app
.
use
(
'
/uploads
'
,
express
.
static
(
'
./uploads
'
));
app
.
use
(
"
/api/users
"
,
userRoutes
);
app
.
use
(
"
/api/users
"
,
userRoutes
);
// app.use("/hardware", hardwareRouter);
app
.
use
(
"
/job
"
,
jobRoutes
)
// app.use("/hardwareItem", hardwareItemRouter);
app
.
use
(
notFound
);
app
.
use
(
notFound
);
app
.
use
(
errorHandler
);
app
.
use
(
errorHandler
);
...
...
frontend/package-lock.json
View file @
f4129b48
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
"name": "pro-hire",
"name": "pro-hire",
"version": "0.1.0",
"version": "0.1.0",
"dependencies": {
"dependencies": {
"@redux-devtools/extension": "^3.2.6",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@testing-library/user-event": "^13.5.0",
...
@@ -18,8 +19,11 @@
...
@@ -18,8 +19,11 @@
"react-datepicker": "^4.21.0",
"react-datepicker": "^4.21.0",
"react-dom": "^18.2.0",
"react-dom": "^18.2.0",
"react-quill": "^2.0.0",
"react-quill": "^2.0.0",
"react-redux": "^8.1.3",
"react-router-dom": "^6.17.0",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
"react-scripts": "5.0.1",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4"
}
}
},
},
...
@@ -3261,6 +3265,18 @@
...
@@ -3261,6 +3265,18 @@
"url": "https://opencollective.com/popperjs"
"url": "https://opencollective.com/popperjs"
}
}
},
},
"node_modules/@redux-devtools/extension": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/@redux-devtools/extension/-/extension-3.2.6.tgz",
"integrity": "sha512-fWrqYAoFFKc5+78P/xWj+3NcoiJ07ak5qdiPTbO5CAuM5vE3dKk5fajpJyuOab+hLNEUJMTklCBYm+WTFcWWxA==",
"dependencies": {
"@babel/runtime": "^7.23.2",
"immutable": "^4.3.4"
},
"peerDependencies": {
"redux": "^3.1.0 || ^4.0.0"
}
},
"node_modules/@remix-run/router": {
"node_modules/@remix-run/router": {
"version": "1.10.0",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.10.0.tgz",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.10.0.tgz",
...
@@ -4034,6 +4050,15 @@
...
@@ -4034,6 +4050,15 @@
"@types/node": "*"
"@types/node": "*"
}
}
},
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": {
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
...
@@ -4464,6 +4489,11 @@
...
@@ -4464,6 +4489,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz",
"integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
"integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
},
},
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/ws": {
"node_modules/@types/ws": {
"version": "8.5.7",
"version": "8.5.7",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.7.tgz",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.7.tgz",
...
@@ -9022,6 +9052,19 @@
...
@@ -9022,6 +9052,19 @@
"he": "bin/he"
"he": "bin/he"
}
}
},
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hoopy": {
"node_modules/hoopy": {
"version": "0.1.4",
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
...
@@ -9313,6 +9356,11 @@
...
@@ -9313,6 +9356,11 @@
"url": "https://opencollective.com/immer"
"url": "https://opencollective.com/immer"
}
}
},
},
"node_modules/immutable": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA=="
},
"node_modules/import-fresh": {
"node_modules/import-fresh": {
"version": "3.3.0",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
...
@@ -14940,6 +14988,49 @@
...
@@ -14940,6 +14988,49 @@
"react-dom": "^16 || ^17 || ^18"
"react-dom": "^16 || ^17 || ^18"
}
}
},
},
"node_modules/react-redux": {
"version": "8.1.3",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
"integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^16.8 || ^17.0 || ^18.0",
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0",
"react-native": ">=0.59",
"redux": "^4 || ^5.0.0-beta.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/react-refresh": {
"node_modules/react-refresh": {
"version": "0.11.0",
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
...
@@ -15105,6 +15196,22 @@
...
@@ -15105,6 +15196,22 @@
"node": ">=8"
"node": ">=8"
}
}
},
},
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/reflect.getprototypeof": {
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
...
@@ -17109,6 +17216,14 @@
...
@@ -17109,6 +17216,14 @@
"requires-port": "^1.0.0"
"requires-port": "^1.0.0"
}
}
},
},
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util-deprecate": {
"node_modules/util-deprecate": {
"version": "1.0.2",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
...
@@ -20301,6 +20416,15 @@
...
@@ -20301,6 +20416,15 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
},
},
"@redux-devtools/extension": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/@redux-devtools/extension/-/extension-3.2.6.tgz",
"integrity": "sha512-fWrqYAoFFKc5+78P/xWj+3NcoiJ07ak5qdiPTbO5CAuM5vE3dKk5fajpJyuOab+hLNEUJMTklCBYm+WTFcWWxA==",
"requires": {
"@babel/runtime": "^7.23.2",
"immutable": "^4.3.4"
}
},
"@remix-run/router": {
"@remix-run/router": {
"version": "1.10.0",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.10.0.tgz",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.10.0.tgz",
...
@@ -20862,6 +20986,15 @@
...
@@ -20862,6 +20986,15 @@
"@types/node": "*"
"@types/node": "*"
}
}
},
},
"@types/hoist-non-react-statics": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": {
"@types/html-minifier-terser": {
"version": "6.1.0",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
...
@@ -21239,6 +21372,11 @@
...
@@ -21239,6 +21372,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz",
"integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
"integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
},
},
"@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"@types/ws": {
"@types/ws": {
"version": "8.5.7",
"version": "8.5.7",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.7.tgz",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.7.tgz",
...
@@ -24541,6 +24679,21 @@
...
@@ -24541,6 +24679,21 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
},
"dependencies": {
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
"hoopy": {
"hoopy": {
"version": "0.1.4",
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
...
@@ -24751,6 +24904,11 @@
...
@@ -24751,6 +24904,11 @@
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
},
},
"immutable": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA=="
},
"import-fresh": {
"import-fresh": {
"version": "3.3.0",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
...
@@ -28649,6 +28807,26 @@
...
@@ -28649,6 +28807,26 @@
"quill": "^1.3.7"
"quill": "^1.3.7"
}
}
},
},
"react-redux": {
"version": "8.1.3",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
"integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"dependencies": {
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
"react-refresh": {
"react-refresh": {
"version": "0.11.0",
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
...
@@ -28769,6 +28947,20 @@
...
@@ -28769,6 +28947,20 @@
"strip-indent": "^3.0.0"
"strip-indent": "^3.0.0"
}
}
},
},
"redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"requires": {}
},
"reflect.getprototypeof": {
"reflect.getprototypeof": {
"version": "1.0.4",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
...
@@ -30233,6 +30425,12 @@
...
@@ -30233,6 +30425,12 @@
"requires-port": "^1.0.0"
"requires-port": "^1.0.0"
}
}
},
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {}
},
"util-deprecate": {
"util-deprecate": {
"version": "1.0.2",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
frontend/package.json
View file @
f4129b48
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
"version"
:
"0.1.0"
,
"version"
:
"0.1.0"
,
"private"
:
true
,
"private"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"@redux-devtools/extension"
:
"^3.2.6"
,
"@testing-library/jest-dom"
:
"^5.17.0"
,
"@testing-library/jest-dom"
:
"^5.17.0"
,
"@testing-library/react"
:
"^13.4.0"
,
"@testing-library/react"
:
"^13.4.0"
,
"@testing-library/user-event"
:
"^13.5.0"
,
"@testing-library/user-event"
:
"^13.5.0"
,
...
@@ -13,8 +14,11 @@
...
@@ -13,8 +14,11 @@
"react-datepicker"
:
"^4.21.0"
,
"react-datepicker"
:
"^4.21.0"
,
"react-dom"
:
"^18.2.0"
,
"react-dom"
:
"^18.2.0"
,
"react-quill"
:
"^2.0.0"
,
"react-quill"
:
"^2.0.0"
,
"react-redux"
:
"^8.1.3"
,
"react-router-dom"
:
"^6.17.0"
,
"react-router-dom"
:
"^6.17.0"
,
"react-scripts"
:
"5.0.1"
,
"react-scripts"
:
"5.0.1"
,
"redux"
:
"^4.2.1"
,
"redux-thunk"
:
"^2.4.2"
,
"web-vitals"
:
"^2.1.4"
"web-vitals"
:
"^2.1.4"
},
},
"scripts"
:
{
"scripts"
:
{
...
...
frontend/src/Component/Job Posting/JobPosting.js
View file @
f4129b48
import
React
,
{
useState
}
from
'
react
'
import
React
,
{
useState
,
useCallback
}
from
'
react
'
import
DatePicker
from
"
react-datepicker
"
;
import
DatePicker
from
"
react-datepicker
"
;
import
ReactQuill
from
"
react-quill
"
;
import
ReactQuill
from
"
react-quill
"
;
import
axios
from
'
axios
'
;
import
"
react-datepicker/dist/react-datepicker.css
"
;
import
"
react-datepicker/dist/react-datepicker.css
"
;
import
"
react-quill/dist/quill.snow.css
"
;
import
"
react-quill/dist/quill.snow.css
"
;
import
'
./JobPosting.css
'
import
'
./JobPosting.css
'
function
JobPosting
()
{
function
JobPosting
()
{
const
[
selectedDate
,
setSelectedDate
]
=
useState
(
new
Date
());
const
[
title
,
setTitle
]
=
useState
(
""
);
const
[
company
,
setCompany
]
=
useState
(
""
);
const
[
location
,
setLocation
]
=
useState
(
""
);
const
[
workType
,
setWorkType
]
=
useState
(
""
);
const
[
term
,
setTerm
]
=
useState
(
""
);
const
[
salary
,
setSalary
]
=
useState
(
""
);
const
[
duration
,
setDuration
]
=
useState
(
""
);
const
[
deadline
,
setDeadline
]
=
useState
(
new
Date
());
const
[
logo
,
setLogo
]
=
useState
(
""
);
const
[
responsibilities
,
setResponsibilities
]
=
useState
(
""
);
const
[
responsibilities
,
setResponsibilities
]
=
useState
(
""
);
const
[
qualifications
,
setQualifications
]
=
useState
(
""
);
const
[
qualifications
,
setQualifications
]
=
useState
(
""
);
const
[
aboutJob
,
setAboutJob
]
=
useState
(
""
);
const
[
aboutJob
,
setAboutJob
]
=
useState
(
""
);
const
handleQuillChange
=
(
content
,
setContent
)
=>
{
// Remove <p> tags from the content
const
strippedContent
=
content
.
replace
(
/<p><
\/
p>/g
,
""
);
// Remove empty <p> tags
const
finalContent
=
strippedContent
.
replace
(
/<p>
(
.*
?)
<
\/
p>/g
,
"
$1
\n
"
);
// Preserve content structure
setContent
(
finalContent
.
trim
());
};
function
sendData
(
e
)
{
e
.
preventDefault
();
const
formData
=
new
FormData
();
formData
.
append
(
"
title
"
,
title
);
formData
.
append
(
"
company
"
,
company
);
formData
.
append
(
"
location
"
,
location
);
formData
.
append
(
"
workType
"
,
workType
);
formData
.
append
(
"
term
"
,
term
);
formData
.
append
(
"
salary
"
,
salary
);
formData
.
append
(
"
duration
"
,
duration
);
formData
.
append
(
"
deadline
"
,
deadline
);
formData
.
append
(
"
logo
"
,
logo
);
formData
.
append
(
"
responsibilities
"
,
responsibilities
);
formData
.
append
(
"
qualifications
"
,
qualifications
);
formData
.
append
(
"
aboutJob
"
,
aboutJob
);
axios
.
post
(
"
http://localhost:8070/job/add
"
,
formData
,
{
headers
:
{
"
Content-Type
"
:
"
multipart/form-data
"
,
},
})
.
then
(()
=>
{
alert
(
"
Job posted successfully
"
);
window
.
location
.
reload
();
})
.
catch
((
err
)
=>
{
alert
(
err
);
});
}
return
(
return
(
<
div
className
=
"
jobPosting
"
>
<
div
className
=
"
jobPosting
"
>
<
form
className
=
"
form-jobPosting
"
>
<
form
className
=
"
form-jobPosting
"
onSubmit
=
{
sendData
}
>
<
div
className
=
"
form-group
"
>
<
div
className
=
"
form-group
"
>
<
label
htmlFor
=
"
jobTitle
"
>
Job
Title
<
/label
>
<
label
htmlFor
=
"
jobTitle
"
>
Job
Title
<
/label
>
<
input
type
=
"
text
"
className
=
"
form-control
"
id
=
"
jobTitle
"
/>
<
input
type
=
"
text
"
className
=
"
form-control
"
id
=
"
jobTitle
"
required
onChange
=
{(
e
)
=>
{
setTitle
(
e
.
target
.
value
);
}}
/
>
<
/div
>
<
/div
>
<
div
className
=
"
form-group
"
>
<
div
className
=
"
form-group
"
>
<
label
htmlFor
=
"
companyName
"
>
Company
Name
<
/label
>
<
label
htmlFor
=
"
companyName
"
>
Company
Name
<
/label
>
<
select
className
=
"
form-control
"
id
=
"
companyName
"
>
<
select
className
=
"
form-control
"
id
=
"
companyName
"
required
onChange
=
{(
e
)
=>
{
setCompany
(
e
.
target
.
value
);
}}
>
<
option
value
=
""
disabled
selected
>
<
option
value
=
""
disabled
selected
>
Select
Company
Select
Company
<
/option
>
<
/option
>
<
option
value
=
"
company1
"
>
Company
1
<
/option
>
<
option
>
InstaHire
<
/option
>
<
option
value
=
"
company2
"
>
Company
2
<
/option
>
<
/select
>
<
/select
>
<
/div
>
<
/div
>
<
div
className
=
"
form-group
"
>
<
div
className
=
"
form-group
"
>
<
label
htmlFor
=
"
location
"
>
Location
<
/label
>
<
label
htmlFor
=
"
location
"
>
Location
<
/label
>
<
select
className
=
"
form-control
"
id
=
"
location
"
>
<
select
className
=
"
form-control
"
id
=
"
location
"
required
onChange
=
{(
e
)
=>
{
setLocation
(
e
.
target
.
value
);
}}
>
<
option
value
=
""
disabled
selected
>
<
option
value
=
""
disabled
selected
>
Select
location
Select
location
<
/option
>
<
/option
>
<
option
value
=
"
location1
"
>
Location
1
<
/option
>
<
option
>
No
:
365
,
Galle
Road
,
Colombo
03
<
/option
>
<
option
value
=
"
location2
"
>
Location
2
<
/option
>
<
/select
>
<
/select
>
<
/div
>
<
/div
>
<
div
className
=
"
d-flex
"
>
<
div
className
=
"
d-flex
"
>
<
div
className
=
"
form-group col-md-6
"
>
<
div
className
=
"
form-group col-md-6
"
>
<
label
htmlFor
=
"
workType
"
>
Work
Type
<
/label
>
<
label
htmlFor
=
"
workType
"
>
Work
Type
<
/label
>
<
select
className
=
"
form-control
"
id
=
"
workType
"
>
<
select
className
=
"
form-control
"
id
=
"
workType
"
required
onChange
=
{(
e
)
=>
{
setWorkType
(
e
.
target
.
value
);
}}
>
<
option
value
=
""
disabled
selected
>
<
option
value
=
""
disabled
selected
>
Select
work
type
Select
work
type
<
/option
>
<
/option
>
<
option
value
=
"
workType1
"
>
Work
Type
1
<
/option
>
<
option
>
On
-
site
<
/option
>
<
option
value
=
"
workType2
"
>
Work
Type
2
<
/option
>
<
option
>
Hybrid
<
/option
>
<
option
>
Online
<
/option
>
<
/select
>
<
/select
>
<
/div
>
<
/div
>
<
div
className
=
"
form-group col-md-6
"
style
=
{{
paddingLeft
:
"
5px
"
}}
>
<
div
className
=
"
form-group col-md-6
"
style
=
{{
paddingLeft
:
"
5px
"
}}
>
<
label
htmlFor
=
"
term
"
>
Term
<
/label
>
<
label
htmlFor
=
"
term
"
>
Term
<
/label
>
<
select
className
=
"
form-control
"
id
=
"
term
"
>
<
select
className
=
"
form-control
"
id
=
"
term
"
required
onChange
=
{(
e
)
=>
{
setTerm
(
e
.
target
.
value
);
}}
>
<
option
value
=
""
disabled
selected
>
<
option
value
=
""
disabled
selected
>
Select
term
Select
term
<
/option
>
<
/option
>
<
option
value
=
"
term1
"
>
Term
1
<
/option
>
<
option
>
Full
-
time
<
/option
>
<
option
value
=
"
term2
"
>
Term
2
<
/option
>
<
option
>
Part
-
time
<
/option
>
<
/select
>
<
/select
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
className
=
"
d-flex
"
>
<
div
className
=
"
d-flex
"
>
<
div
className
=
"
form-group col-md-6
"
>
<
div
className
=
"
form-group col-md-6
"
>
<
label
htmlFor
=
"
salary
"
>
Salary
<
/label
>
<
label
htmlFor
=
"
salary
"
>
Salary
<
/label
>
<
input
type
=
"
number
"
className
=
"
form-control
"
id
=
"
salary
"
/>
<
input
type
=
"
number
"
className
=
"
form-control
"
id
=
"
salary
"
required
onChange
=
{(
e
)
=>
{
setSalary
(
e
.
target
.
value
);
}}
/
>
<
/div
>
<
/div
>
<
div
className
=
"
form-group col-md-6
"
style
=
{{
paddingLeft
:
"
5px
"
}}
>
<
div
className
=
"
form-group col-md-6
"
style
=
{{
paddingLeft
:
"
5px
"
}}
>
<
label
htmlFor
=
"
duration
"
>
Duration
<
/label
>
<
label
htmlFor
=
"
duration
"
>
Duration
<
/label
>
<
select
className
=
"
form-control
"
id
=
"
duration
"
>
<
select
className
=
"
form-control
"
id
=
"
duration
"
required
onChange
=
{(
e
)
=>
{
setDuration
(
e
.
target
.
value
);
}}
>
<
option
value
=
""
disabled
selected
>
<
option
value
=
""
disabled
selected
>
Select
duration
Select
duration
<
/option
>
<
/option
>
<
option
value
=
"
duration1
"
>
Duration
1
<
/option
>
<
option
>
6
months
<
/option
>
<
option
value
=
"
duration2
"
>
Duration
2
<
/option
>
<
option
>
1
year
<
/option
>
<
option
>
2
year
<
/option
>
<
/select
>
<
/select
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -83,8 +183,8 @@ function JobPosting() {
...
@@ -83,8 +183,8 @@ function JobPosting() {
<
DatePicker
<
DatePicker
className
=
"
form-control
"
className
=
"
form-control
"
id
=
"
deadline
"
id
=
"
deadline
"
selected
=
{
selectedDat
e
}
selected
=
{
deadlin
e
}
onChange
=
{(
date
)
=>
set
SelectedDat
e
(
date
)}
onChange
=
{(
date
)
=>
set
Deadlin
e
(
date
)}
/
>
/
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -95,9 +195,13 @@ function JobPosting() {
...
@@ -95,9 +195,13 @@ function JobPosting() {
<
label
htmlFor
=
"
logo
"
>
Logo
<
/label
>
<
label
htmlFor
=
"
logo
"
>
Logo
<
/label
>
<
input
<
input
type
=
"
file
"
type
=
"
file
"
name
=
"
logo
"
className
=
"
form-control-file
"
className
=
"
form-control-file
"
id
=
"
logo
"
id
=
"
logo
"
accept
=
"
image/*
"
required
onChange
=
{(
e
)
=>
{
setLogo
(
e
.
target
.
files
[
0
]);
}}
/
>
/
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -106,7 +210,9 @@ function JobPosting() {
...
@@ -106,7 +210,9 @@ function JobPosting() {
<
ReactQuill
<
ReactQuill
theme
=
"
snow
"
theme
=
"
snow
"
value
=
{
responsibilities
}
value
=
{
responsibilities
}
onChange
=
{
setResponsibilities
}
onChange
=
{(
content
)
=>
handleQuillChange
(
content
,
setResponsibilities
)
}
/
>
/
>
<
/div
>
<
/div
>
...
@@ -115,16 +221,24 @@ function JobPosting() {
...
@@ -115,16 +221,24 @@ function JobPosting() {
<
ReactQuill
<
ReactQuill
theme
=
"
snow
"
theme
=
"
snow
"
value
=
{
qualifications
}
value
=
{
qualifications
}
onChange
=
{
setQualifications
}
onChange
=
{(
content
)
=>
handleQuillChange
(
content
,
setQualifications
)
}
/
>
/
>
<
/div
>
<
/div
>
<
div
className
=
"
form-group
"
>
<
div
className
=
"
form-group
"
>
<
label
htmlFor
=
"
aboutJob
"
>
About
the
Job
<
/label
>
<
label
htmlFor
=
"
aboutJob
"
>
About
the
Job
<
/label
>
<
ReactQuill
theme
=
"
snow
"
value
=
{
aboutJob
}
onChange
=
{
setAboutJob
}
/
>
<
ReactQuill
theme
=
"
snow
"
value
=
{
aboutJob
}
onChange
=
{(
content
)
=>
handleQuillChange
(
content
,
setAboutJob
)}
/
>
<
/div
>
<
/div
>
<
div
style
=
{{
paddingTop
:
"
10px
"
}}
>
<
div
style
=
{{
paddingTop
:
"
10px
"
}}
>
<
button
className
=
'
btn btn-primary
'
type
=
"
submit
"
>
Post
Job
<
/button
>
<
button
className
=
"
btn btn-primary
"
type
=
"
submit
"
>
Post
Job
<
/button
>
<
/div
>
<
/div
>
<
/form
>
<
/form
>
<
/div
>
<
/div
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment