Merge pull request 'chore: Update branch' (#6) from Maradona/Backend:restfull into main
Reviewed-on: 2210970/Backend#6pull/1/head
commit
10cd08583b
|
@ -31,3 +31,11 @@ build/
|
|||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
.history/
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
|
||||
### Database files ###
|
||||
*.db
|
||||
*.mv.db
|
||||
|
|
Binary file not shown.
1
pom.xml
1
pom.xml
|
@ -102,6 +102,7 @@
|
|||
<destDir>${project.build.directory}/docs</destDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -33,13 +33,13 @@ public class DefaultValueLoader implements CommandLineRunner {
|
|||
private FormOfAddressRepository formOfAddressRepository;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
public void run(String... args) {
|
||||
|
||||
// Clear all tables
|
||||
// formOfAddressRepository.deleteAll();
|
||||
// employeeRepository.deleteAll();
|
||||
// secondarySkillRepository.deleteAll();
|
||||
// primarySkillRepository.deleteAll();
|
||||
employeeRepository.deleteAll();
|
||||
secondarySkillRepository.deleteAll();
|
||||
primarySkillRepository.deleteAll();
|
||||
formOfAddressRepository.deleteAll();
|
||||
|
||||
// Create form of addresses
|
||||
FormOfAddress formOfAddress1 = new FormOfAddress();
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package com.maradona.backend.controllers.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.maradona.backend.entities.FormOfAddress;
|
||||
import com.maradona.backend.services.FormOfAddressService;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
|
||||
/**
|
||||
* Controller for routing to the form of address related API endpoints.
|
||||
*
|
||||
* List of endpoints:
|
||||
* - GET /api/form-of-adress
|
||||
* - GET /api/form-of-adress/all
|
||||
* - POST /api/form-of-adress
|
||||
* - PUT /api/form-of-adress
|
||||
* - DELETE /api/form-of-adress
|
||||
*
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/form-of-adress")
|
||||
class FormOfAdressController {
|
||||
|
||||
@Autowired
|
||||
private FormOfAddressService formOfAdressService;
|
||||
|
||||
/**
|
||||
* Returns the form of address with the given ID.
|
||||
*
|
||||
* @param id The ID of the form of address to return.
|
||||
* @return The description of the form of address with the given ID.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public ResponseEntity<FormOfAddress> getFormOfAdress(@RequestParam Long id) {
|
||||
return formOfAdressService.getFormOfAddressById(id)
|
||||
.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all form of addresses.
|
||||
*
|
||||
* @return A list of all form of addresses.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@GetMapping("/all")
|
||||
public ResponseEntity<Iterable<FormOfAddress>> getAllFormOfAdresses() {
|
||||
Iterable<FormOfAddress> formOfAddresses = formOfAdressService.getAllFormOfAddresses();
|
||||
return ResponseEntity.ok(formOfAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new form of address.
|
||||
*
|
||||
* @param description The description of the new form of address.
|
||||
* @return The ID of the newly created form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@PostMapping({ "/", "" })
|
||||
public ResponseEntity<Void> createFormOfAdress(@RequestBody String description) {
|
||||
var formOfAddress = new FormOfAddress();
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAdressService.saveFormOfAddress(formOfAddress);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the description of a form of address.
|
||||
*
|
||||
* @param id The ID of the form of address to update.
|
||||
* @param description The new description of the form of address.
|
||||
* @return The updated form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@PutMapping({ "/", "" })
|
||||
public ResponseEntity<Void> updateFormOfAdress(@RequestParam Long id, @RequestBody String description) {
|
||||
var formOfAddress = formOfAdressService.getFormOfAddressById(id).orElse(null);
|
||||
if (formOfAddress == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAdressService.saveFormOfAddress(formOfAddress);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a form of address.
|
||||
*
|
||||
* @param id The ID of the form of address to delete.
|
||||
* @return The deleted form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@DeleteMapping({ "/", "" })
|
||||
public ResponseEntity<Void> deleteFormOfAdress(@RequestParam Long id) {
|
||||
var formOfAddress = formOfAdressService.getFormOfAddressById(id).orElse(null);
|
||||
if (formOfAddress == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
formOfAdressService.deleteFormOfAddress(id);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}
|
|
@ -9,21 +9,21 @@ public class Page {
|
|||
|
||||
@GetMapping({ "/", "" })
|
||||
public String home(Model model) {
|
||||
return "redirect:/projects";
|
||||
return "pages/core/home";
|
||||
}
|
||||
|
||||
@GetMapping("/impressum")
|
||||
public String impressum() {
|
||||
return "core/impressum";
|
||||
return "pages/core/impressum";
|
||||
}
|
||||
|
||||
@GetMapping("/datenschutz")
|
||||
public String datenschutz() {
|
||||
return "core/datenschutz";
|
||||
return "pages/core/datenschutz";
|
||||
}
|
||||
|
||||
@GetMapping("/notes")
|
||||
public String notes() {
|
||||
return "notes/notes";
|
||||
return "pages/core/notes";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.maradona.backend.services.ProjectService;
|
|||
* - GET /projects
|
||||
* - GET /projects/create
|
||||
*
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/projects")
|
||||
|
@ -32,13 +32,13 @@ public class ProjectPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The projects overview page template
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public String projects(Model model) {
|
||||
var projects = projectService.getAllProjects();
|
||||
model.addAttribute("projects", projects);
|
||||
return "projects/projects";
|
||||
return "/pages/projects/overview";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,11 +46,11 @@ public class ProjectPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The project creation page template
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@GetMapping("/create")
|
||||
public String create(Model model) {
|
||||
model.addAttribute("project", new Project());
|
||||
return "projects/projects-create";
|
||||
return "/pages/projects/create";
|
||||
}
|
||||
}
|
|
@ -7,8 +7,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.stereotype.Controller;
|
||||
|
||||
import com.maradona.backend.entities.SecondarySkill;
|
||||
import com.maradona.backend.entities.Employee;
|
||||
import com.maradona.backend.entities.PrimarySkill;
|
||||
import com.maradona.backend.services.EmployeeService;
|
||||
import com.maradona.backend.services.SkillService;
|
||||
import com.maradona.backend.services.PrimarySkillService;
|
||||
|
@ -22,6 +20,7 @@ import com.maradona.backend.dto.SkillPrototype;
|
|||
* - GET /skills/create
|
||||
* - GET /skills/add
|
||||
*
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/skills")
|
||||
|
@ -47,15 +46,15 @@ public class SkillsPage {
|
|||
* "employee" and a SkillsDto object "skills".
|
||||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The skills overview page template
|
||||
* @see Employee
|
||||
* @see SkillsDto
|
||||
* @return The skills overview page template.
|
||||
* @see com.maradona.backend.entities.Employee
|
||||
* @see com.maradona.backend.dto.SkillsDto
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public String profile(Model model) {
|
||||
model.addAttribute("employee", employeeService.getEmployeeById(user).orElse(null));
|
||||
model.addAttribute("skills", skillService.getUserSkills(user));
|
||||
return "skills/skills";
|
||||
return "/pages/skills/overview";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,12 +65,12 @@ public class SkillsPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed
|
||||
* @return The create skill page template
|
||||
* @see SecondarySkill
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
*/
|
||||
@GetMapping("/create")
|
||||
public String createSkill(Model model) {
|
||||
model.addAttribute("secondarySkill", new SecondarySkill());
|
||||
return "skills/skills-create";
|
||||
return "/pages/skills/create";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,16 +86,16 @@ public class SkillsPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed
|
||||
* @return The add skill page template
|
||||
* @see PrimarySkill
|
||||
* @see SecondarySkill
|
||||
* @see SkillPrototype
|
||||
* @see com.maradona.backend.entities.PrimarySkill
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
* @see com.maradona.backend.dto.SkillPrototype
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String addSkill(Model model) {
|
||||
// TODO: Make sure it returns the correct initail data for secondary skills
|
||||
model.addAttribute("primarySkills", primarySkillService.getAllPrimarySkills());
|
||||
model.addAttribute("skillProtoype", new SkillPrototype());
|
||||
return "skills/skills-add";
|
||||
return "/pages/skills/add";
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.maradona.backend.entities;
|
|||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -10,7 +11,6 @@ import java.util.stream.Collectors;
|
|||
@Entity
|
||||
@Data
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
@ -31,6 +31,7 @@ public class Employee {
|
|||
private LocalTime dEnd;
|
||||
|
||||
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JsonManagedReference
|
||||
private List<EmployeeSecondarySkill> secondarySkills;
|
||||
|
||||
public void setEmployeeNr(Integer employeeNr) {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.maradona.backend.entities;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class EmployeeSecondarySkill {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
@ -19,7 +18,6 @@ public class EmployeeSecondarySkill {
|
|||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "secondary_skill_id", nullable = false)
|
||||
@JsonBackReference
|
||||
private SecondarySkill secondarySkill;
|
||||
|
||||
@Column(nullable = false)
|
||||
|
|
|
@ -28,4 +28,14 @@ public class FormOfAddressService {
|
|||
public Iterable<FormOfAddress> getAllFormOfAddresses() {
|
||||
return formOfAddressRepository.findAll();
|
||||
}
|
||||
|
||||
public Long updateFormOfAddress(Long id, String description) {
|
||||
var formOfAddress = formOfAddressRepository.findById(id).orElse(null);
|
||||
if (formOfAddress != null) {
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAddressRepository.save(formOfAddress);
|
||||
return id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
document.getElementById("primarySkill").addEventListener("change", function () {
|
||||
var primarySkillId = this.value;
|
||||
fetch("/skills/secondary-skills?primarySkillId=" + primarySkillId)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log("Fetch response data:", data);
|
||||
var secondarySkillSelect = document.getElementById("secondarySkill");
|
||||
secondarySkillSelect.innerHTML =
|
||||
'<option value="" disabled selected>Select a secondary skill</option>';
|
||||
data.forEach(function (secondarySkill) {
|
||||
var option = document.createElement("option");
|
||||
option.value = secondarySkill.ssid;
|
||||
option.text = secondarySkill.description;
|
||||
secondarySkillSelect.add(option);
|
||||
});
|
||||
})
|
||||
.catch((error) => console.error("Error fetching secondary skills:", error));
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
/* Placeholder */
|
|
@ -5,26 +5,9 @@
|
|||
<img src="/assets/inter-brand.svg" alt="INTER Logo" class="svg-logo" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<nav>
|
||||
<ul class="nav justify-content-end">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/projects}"
|
||||
th:classappend="${activePage == 'projects' ? 'active' : ''}"
|
||||
>Projekte</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/skills}"
|
||||
th:classappend="${activePage == 'profile' ? 'active' : ''}"
|
||||
>Skills</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div
|
||||
th:replace="~{/core/_navigation :: navigation(activePage=${activePage})}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div th:fragment="navigation">
|
||||
<nav>
|
||||
<ul class="nav justify-content-end">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/projects}"
|
||||
th:classappend="${activePage == 'projects' ? 'active' : ''}"
|
||||
>Projekte</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/skills}"
|
||||
th:classappend="${activePage == 'profile' ? 'active' : ''}"
|
||||
>Skills</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>My Skill Management System</title>
|
||||
<link rel="stylesheet" href="style/notes/notes.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div th:replace="~{/core/_header :: header(activePage=${notes})}"></div>
|
||||
<div class="content container mt-4"></div>
|
||||
<div th:replace="~{/core/_footer :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Create Project</title>
|
||||
<link rel="stylesheet" href="/style/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,7 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Projects</title>
|
||||
<link rel="stylesheet" href="/style/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Add Skill</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
|
@ -15,11 +15,12 @@
|
|||
<h2 class="mb-4">Add Skill</h2>
|
||||
<form
|
||||
th:action="@{/skills/add}"
|
||||
th:object="${skillForm}"
|
||||
th:object="${skillProtoype}"
|
||||
method="post"
|
||||
class="project-card"
|
||||
>
|
||||
<div class="card-body">
|
||||
<!-- Primary Skill Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="primarySkill">Primary Skill</label>
|
||||
<select
|
||||
|
@ -28,6 +29,9 @@
|
|||
class="form-control"
|
||||
th:field="*{primarySkillId}"
|
||||
>
|
||||
<option value="" disabled selected>
|
||||
Select a primary skill
|
||||
</option>
|
||||
<option
|
||||
th:each="primarySkill : ${primarySkills}"
|
||||
th:value="${primarySkill.psid}"
|
||||
|
@ -35,6 +39,8 @@
|
|||
></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Secondary Skill Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="secondarySkill">Secondary Skill</label>
|
||||
<select
|
||||
|
@ -48,6 +54,8 @@
|
|||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Skill Level Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="level">Level</label>
|
||||
<select
|
||||
|
@ -56,6 +64,7 @@
|
|||
class="form-control"
|
||||
th:field="*{level}"
|
||||
>
|
||||
<option value="" disabled selected>Select skill level</option>
|
||||
<option
|
||||
th:each="level : ${#numbers.sequence(1, 5)}"
|
||||
th:value="${level}"
|
||||
|
@ -63,36 +72,14 @@
|
|||
></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button type="submit" class="btn-create-project">Add Skill</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div th:replace="~{/core/_footer :: footer}"></div>
|
||||
</div>
|
||||
<script>
|
||||
document
|
||||
.getElementById("primarySkill")
|
||||
.addEventListener("change", function () {
|
||||
var primarySkillId = this.value;
|
||||
fetch("/skills/secondary-skills?primarySkillId=" + primarySkillId)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log("Fetch response data:", data);
|
||||
var secondarySkillSelect =
|
||||
document.getElementById("secondarySkill");
|
||||
secondarySkillSelect.innerHTML =
|
||||
'<option value="" disabled selected>Select a secondary skill</option>';
|
||||
data.forEach(function (secondarySkill) {
|
||||
var option = document.createElement("option");
|
||||
option.value = secondarySkill.ssid;
|
||||
option.text = secondarySkill.description;
|
||||
secondarySkillSelect.add(option);
|
||||
});
|
||||
})
|
||||
.catch((error) =>
|
||||
console.error("Error fetching secondary skills:", error)
|
||||
);
|
||||
});
|
||||
</script>
|
||||
<script src="/js/skills/fetchSecondarySkills.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Create Skill</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,8 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Skills</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
Loading…
Reference in New Issue