Додаток для пошуку роботи за допомогою React та Spring Boot!

pic

Цей веб-додаток створено за допомогою SpringBoot, Java, Node.js, React
Щасливого копіювання та вставлення.

pic

package com.sundaran.spring_boot_rest.model;  

import jakarta.persistence.Entity;  
import jakarta.persistence.Id;  
import lombok.AllArgsConstructor;  
import lombok.Data;  
import lombok.NoArgsConstructor;  
import org.springframework.stereotype.Component;  


import java.util.List;  

@Data  
@NoArgsConstructor  
@AllArgsConstructor  
@Component  
@Entity  
public class JobPost {  
 @Id  
 private int postId;  
 private String postProfile;  
 private String postDesc;  
 private int reqExperience;  
 private List postTechStack;  

}
package com.sundaran.spring_boot_rest.repo;  

import com.sundaran.spring_boot_rest.model.JobPost;  
import org.springframework.data.jpa.repository.JpaRepository;  
import org.springframework.stereotype.Repository;  

import java.util.List;  


@Repository  
public interface JobRepo extends JpaRepository{  
 List findByPostProfileContainingOrPostDescContaining(String postProfile,String postDesc);  
}
package com.sundaran.spring_boot_rest;  

import com.sundaran.spring_boot_rest.model.JobPost;  
import com.sundaran.spring_boot_rest.service.JobService;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.*;  

import java.util.List;  

@RestController  
@CrossOrigin(origins = "http://localhost:3000")  
public class JobRestController {  

 @Autowired  
 private JobService service;  

 @GetMapping(path="jobPosts",produces = {"application/json"})  
 public List getAllJobs(){  
 return service.getAllJobs();  
 }  

 @GetMapping("jobPost/{postId}")  
 public JobPost getJob(@PathVariable int postId){  
 return service.getJob(postId);  
 }  

 @GetMapping("jobPost/keyword/{keyword}")  
 public List searchByKeyword(@PathVariable("keyword") String keyword){  
 return service.search(keyword);  
 }  

 @PostMapping(path="jobPost",consumes = "application/json")  
 public JobPost addJob(@RequestBody JobPost jobPost){  
 service.addJob(jobPost);  
 return service.getJob(jobPost.getPostId());  
 }  

 @PutMapping("jobPost")  
 public JobPost updateJob(@RequestBody JobPost jobPost){  
 service.updateJob(jobPost);  
 return service.getJob(jobPost.getPostId());  
 }  

 @DeleteMapping("jobPost/{postId}")  
 public String deleteJob(@PathVariable int postId){  
 service.deleteJob(postId);  
 return "Deleted";  
 }  

 @GetMapping("load")  
 public String loadData(){  
 service.load();  
 return "success";  
 }  
}
package com.sundaran.spring_boot_rest;  

import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  

@SpringBootApplication  
public class SpringBootRestApplication {  

 public static void main(String[] args) {  
 SpringApplication.run(SpringBootRestApplication.class, args);  
 }  

}
spring.application.name=spring-boot-rest  

spring.datasource.url=jdbc:postgresql://localhost:5433/sundaran  
spring.datasource.username=postgres  
spring.datasource.password=  
spring.datasource.driver-class-name=org.postgresql.Driver  

spring.jpa.hibernate.ddl-auto=update  
spring.jpl.show-sql=true

pic

import React, { useState, useEffect } from "react";  
import {  
 AppBar,  
 Toolbar,  
 Box,  
 Card,  
 Grid,  
 Typography,  
 Button,  
 TextField,  
 IconButton,  
 Container,  
 Fab,  
 Drawer,  
 Divider,  
} from "@mui/material";  
import SearchIcon from "@mui/icons-material/Search";
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";  
import DeleteIcon from "@mui/icons-material/Delete";  
import EditIcon from "@mui/icons-material/Edit";  
import CloseIcon from "@mui/icons-material/Close";  
import axios from "axios";  

const Search = () => {  
 const [posts, setPosts] = useState([]);  
 const [newPost, setNewPost] = useState({  
 postId: "",  
 postProfile: "",  
 postDesc: "",  
 reqExperience: "",  
 postTechStack: [],  
 });  
 const [searchKeyword, setSearchKeyword] = useState("");  
 const [editMode, setEditMode] = useState(false);  
 const [drawerOpen, setDrawerOpen] = useState(false);  

 const fetchAllPosts = async () => {  
 try {  
 const response = await axios.get("http://localhost:8080/jobPosts");  
 setPosts(response.data);  
 } catch (error) {  
 console.error("Помилка при отриманні вакансій:", error);  
 }  
 };  

 const fetchFilteredPosts = async (keyword) => {  
 try {  
 const response = await axios.get(  
 `http://localhost:8080/jobPost/keyword/${keyword}`  
 );  
 setPosts(response.data);  
 } catch (error) {  
 console.error("Помилка при отриманні фільтрованих вакансій:", error);  
 }  
 };  

 const deletePost = async (postId) => {  
 try {  
 await axios.delete(`http://localhost:8080/jobPost/${postId}`);  
 fetchAllPosts();  
 } catch (error) {  
 console.error("Помилка при видаленні вакансії:", error);  
 }  
 };  

 const addPost = async () => {  
 try {  
 await axios.post("http://localhost:8080/jobPost", newPost);  
 fetchAllPosts();  
 resetForm();  
 setDrawerOpen(false);  
 } catch (error) {  
 console.error("Помилка при додаванні вакансії:", error);  
 }  
 };  

 const updatePost = async () => {  
 try {  
 await axios.put("http://localhost:8080/jobPost", newPost);  
 fetchAllPosts();  
 resetForm();  
 setDrawerOpen(false);  
 } catch (error) {  
 console.error("Помилка при оновленні вакансії:", error);  
 }  
 };  

 const resetForm = () => {  
 setNewPost({  
 postId: "",  
 postProfile: "",  
 postDesc: "",  
 reqExperience: "",  
 postTechStack: [],  
 });  
 setEditMode(false);  
 };  

 const handleSearchChange = (event) => {  
 const keyword = event.target.value;  
 setSearchKeyword(keyword);  
 if (keyword) {  
 fetchFilteredPosts(keyword);  
 } else {  
 fetchAllPosts();  
 }  
 };  

 useEffect(() => {  
 fetchAllPosts();  
 }, []);  

 return (  

 {/* AppBar */}  



 Job Portal  




 {/* Основний контейнер */}  

 {/* Пошукова панель */}  




 ),  
 }}  
 sx={{  
 borderRadius: "8px",  
 backgroundColor: "#fff",  
 boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.1)",  
 "& .MuiOutlinedInput-root": {  
 color: "#333",  
 "& fieldset": {  
 borderColor: "#ccc",  
 },  
 },  
 }}  
 />  


 {/* Інструктивний текст */}  


 Хочете додати вакансію?  


 Натисніть на плаваючу кнопку нижче, щоб додати нову вакансію до порталу.
{/* Сітка вакансій */}  

 {posts.map((p) => (  



 {p.postProfile}  


 {p.postDesc}  


 Технології: {p.postTechStack.join(", ")}  
 Досвід: {p.reqExperience} років  


  deletePost(p.postId)}  
 >  


  {  
 setEditMode(true);  
 setNewPost(p);  
 setDrawerOpen(true);  
 }}  
 >  





 ))}  


 {/* Плаваюча кнопка для додавання вакансії */}  
  {  
 setEditMode(false);  
 setDrawerOpen(true);  
 }}  
 >  



 {/* Бічна панель для додавання/редагування вакансії */}  
  setDrawerOpen(false)}  
 sx={{  
 "& .MuiDrawer-paper": {  
 width: "400px",  
 padding: "20px",  
 backgroundColor: "#fff",  
 boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)",  
 },  
 }}  
 >  


 {editMode ? "Редагувати вакансію" : "Додати нову вакансію"}  

  setDrawerOpen(false)}>  




  setNewPost({ ...newPost, postId: e.target.value })}  
 fullWidth  
 disabled={editMode}  
 sx={{  
 backgroundColor: "#fff",  
 boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.1)",  
 "& .MuiOutlinedInput-root": {  
 color: "#333",  
 "& fieldset": {  
 borderColor: "#ccc",  
 },  
 },  
 }}  
 />  
  setNewPost({ ...newPost, postProfile: e.target.value })}  
 fullWidth  
 sx={{ marginTop: "20px" }}  
 />  
  setNewPost({ ...newPost, postDesc: e.target.value })}  
 fullWidth  
 sx={{ marginTop: "20px" }}  
 />  
  setNewPost({ ...newPost, reqExperience: e.target.value })}  
 fullWidth  
 sx={{ marginTop: "20px" }}  
 />  
 setNewPost({ ...newPost, postTechStack: e.target.value.split(",").map(item => item.trim()) })}  
 fullWidth  
 sx={{  
 marginTop: "20px",  
 backgroundColor: "#fff",  
 "& .MuiOutlinedInput-root": {  
 color: "#333",  
 },  
 }}  
/>
variant="contained"  
 color="primary"  
 onClick={editMode ? updatePost : addPost}  
 >  
 {editMode ? "Оновити вакансію" : "Додати вакансію"}  





 );  
};  

export default Search;  




Перекладено з: [Job App Using React and Spring Boot !](https://sundaran13.medium.com/job-app-using-react-and-spring-boot-89fe0939a1cc)

Leave a Reply

Your email address will not be published. Required fields are marked *