Skip to content

Commit 7474a7c

Browse files
committed
Use backend-driven category options for resource filters
1 parent e5b35c1 commit 7474a7c

File tree

11 files changed

+1117
-110
lines changed

11 files changed

+1117
-110
lines changed

backend/src/main/java/com/thughari/jobtrackerpro/controller/CareerResourceController.java

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
package com.thughari.jobtrackerpro.controller;
22

33
import com.thughari.jobtrackerpro.dto.CareerResourceDTO;
4+
import com.thughari.jobtrackerpro.dto.CareerResourcePageResponse;
45
import com.thughari.jobtrackerpro.dto.CreateCareerResourceRequest;
6+
import com.thughari.jobtrackerpro.dto.UpdateCareerResourceRequest;
57
import com.thughari.jobtrackerpro.service.CareerResourceService;
8+
import org.springframework.http.MediaType;
69
import org.springframework.http.ResponseEntity;
10+
import org.springframework.security.authentication.AnonymousAuthenticationToken;
11+
import org.springframework.security.core.Authentication;
712
import org.springframework.security.core.context.SecurityContextHolder;
13+
import org.springframework.web.bind.annotation.DeleteMapping;
814
import org.springframework.web.bind.annotation.GetMapping;
15+
import org.springframework.web.bind.annotation.PathVariable;
916
import org.springframework.web.bind.annotation.PostMapping;
17+
import org.springframework.web.bind.annotation.PutMapping;
1018
import org.springframework.web.bind.annotation.RequestBody;
1119
import org.springframework.web.bind.annotation.RequestMapping;
20+
import org.springframework.web.bind.annotation.RequestParam;
1221
import org.springframework.web.bind.annotation.RestController;
22+
import org.springframework.web.multipart.MultipartFile;
1323

24+
import java.util.UUID;
1425
import java.util.List;
1526

1627
@RestController
@@ -24,8 +35,20 @@ public CareerResourceController(CareerResourceService careerResourceService) {
2435
}
2536

2637
@GetMapping
27-
public ResponseEntity<List<CareerResourceDTO>> getResources() {
28-
return ResponseEntity.ok(careerResourceService.getAllResources());
38+
public ResponseEntity<CareerResourcePageResponse> getResources(
39+
@RequestParam(defaultValue = "0") int page,
40+
@RequestParam(defaultValue = "20") int size,
41+
@RequestParam(required = false) String query,
42+
@RequestParam(required = false) String category,
43+
@RequestParam(required = false) String type
44+
) {
45+
return ResponseEntity.ok(careerResourceService.getResourcePage(page, size, query, category, type, getAuthenticatedEmailOrNull()));
46+
}
47+
48+
49+
@GetMapping("/categories")
50+
public ResponseEntity<List<String>> getCategories() {
51+
return ResponseEntity.ok(careerResourceService.getAllCategories());
2952
}
3053

3154
@PostMapping
@@ -34,7 +57,52 @@ public ResponseEntity<CareerResourceDTO> addResource(@RequestBody CreateCareerRe
3457
return ResponseEntity.ok(careerResourceService.createResource(email, request));
3558
}
3659

60+
@GetMapping("/mine")
61+
public ResponseEntity<List<CareerResourceDTO>> getMyResources() {
62+
String email = getAuthenticatedEmail();
63+
return ResponseEntity.ok(careerResourceService.getMyResources(email));
64+
}
65+
66+
@PutMapping("/{id}")
67+
public ResponseEntity<CareerResourceDTO> updateResource(@PathVariable UUID id,
68+
@RequestBody UpdateCareerResourceRequest request) {
69+
String email = getAuthenticatedEmail();
70+
return ResponseEntity.ok(careerResourceService.updateResource(email, id, request));
71+
}
72+
73+
@PostMapping(path = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
74+
public ResponseEntity<CareerResourceDTO> uploadResource(
75+
@RequestParam String title,
76+
@RequestParam String category,
77+
@RequestParam(required = false) String description,
78+
@RequestParam MultipartFile file
79+
) {
80+
String email = getAuthenticatedEmail();
81+
return ResponseEntity.ok(careerResourceService.createResourceFromFile(email, title, category, description, file));
82+
}
83+
84+
@DeleteMapping("/{id}")
85+
public ResponseEntity<Void> deleteResource(@PathVariable UUID id) {
86+
String email = getAuthenticatedEmail();
87+
careerResourceService.deleteResource(email, id);
88+
return ResponseEntity.noContent().build();
89+
}
90+
3791
private String getAuthenticatedEmail() {
3892
return ((String) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).toLowerCase();
3993
}
94+
95+
private String getAuthenticatedEmailOrNull() {
96+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
97+
if (authentication == null || !authentication.isAuthenticated() || authentication instanceof AnonymousAuthenticationToken) {
98+
return null;
99+
}
100+
101+
Object principal = authentication.getPrincipal();
102+
if (principal instanceof String email && !"anonymousUser".equalsIgnoreCase(email)) {
103+
return email.toLowerCase();
104+
}
105+
106+
return null;
107+
}
40108
}

backend/src/main/java/com/thughari/jobtrackerpro/dto/CareerResourceDTO.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ public class CareerResourceDTO {
1212
private String url;
1313
private String category;
1414
private String description;
15+
private String resourceType;
16+
private String originalFileName;
17+
private Long fileSizeBytes;
18+
private boolean ownedByCurrentUser;
1519
private String submittedByName;
1620
private LocalDateTime createdAt;
1721
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.thughari.jobtrackerpro.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
6+
import java.util.List;
7+
8+
@Data
9+
@AllArgsConstructor
10+
public class CareerResourcePageResponse {
11+
private List<CareerResourceDTO> content;
12+
private int page;
13+
private int size;
14+
private long totalElements;
15+
private int totalPages;
16+
private boolean hasNext;
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.thughari.jobtrackerpro.dto;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class UpdateCareerResourceRequest {
7+
private String title;
8+
private String url;
9+
private String category;
10+
private String description;
11+
}

backend/src/main/java/com/thughari/jobtrackerpro/entity/CareerResource.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,20 @@ public class CareerResource {
2828
@Column(nullable = false, length = 2048)
2929
private String url;
3030

31+
@Column(nullable = false, length = 16)
32+
private String resourceType = "LINK";
33+
3134
@Column(nullable = false, length = 80)
3235
private String category;
3336

3437
@Column(length = 1200)
3538
private String description;
3639

40+
@Column(length = 255)
41+
private String originalFileName;
42+
43+
private Long fileSizeBytes;
44+
3745
@Column(nullable = false)
3846
private String submittedByEmail;
3947

backend/src/main/java/com/thughari/jobtrackerpro/repo/CareerResourceRepository.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22

33
import com.thughari.jobtrackerpro.entity.CareerResource;
44
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6+
import org.springframework.data.jpa.repository.Query;
7+
import org.springframework.data.domain.Page;
8+
import org.springframework.data.domain.Pageable;
59

610
import java.util.List;
711
import java.util.UUID;
812

9-
public interface CareerResourceRepository extends JpaRepository<CareerResource, UUID> {
13+
public interface CareerResourceRepository extends JpaRepository<CareerResource, UUID>, JpaSpecificationExecutor<CareerResource> {
1014
List<CareerResource> findAllByOrderByCreatedAtDesc();
1115

16+
Page<CareerResource> findAllByOrderByCreatedAtDesc(Pageable pageable);
17+
18+
List<CareerResource> findAllBySubmittedByEmailOrderByCreatedAtDesc(String email);
19+
20+
@Query("select distinct r.category from CareerResource r where r.category is not null and trim(r.category) <> '' order by r.category asc")
21+
List<String> findDistinctCategories();
22+
1223
boolean existsByUrl(String url);
1324
}

0 commit comments

Comments
 (0)