feat: Add initial frontend dependencies, base CSS, and Gitea Docker build workflow.
Some checks failed
Build and Push Docker Images / build-and-push (push) Failing after 2m23s
Some checks failed
Build and Push Docker Images / build-and-push (push) Failing after 2m23s
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.todo.backend;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class BackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BackendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
18
backend/src/main/java/com/todo/backend/config/WebConfig.java
Normal file
18
backend/src/main/java/com/todo/backend/config/WebConfig.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.todo.backend.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/api/**")
|
||||
.allowedOrigins("http://localhost:5173", "http://localhost:3000", "http://localhost:8081", "http://localhost:80") // Typical Vite/React/Docker ports
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.todo.backend.controller;
|
||||
|
||||
import com.todo.backend.model.Todo;
|
||||
import com.todo.backend.service.TodoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/todos")
|
||||
public class TodoController {
|
||||
|
||||
private final TodoService todoService;
|
||||
|
||||
@Autowired
|
||||
public TodoController(TodoService todoService) {
|
||||
this.todoService = todoService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<Todo>> getAllTodos() {
|
||||
return new ResponseEntity<>(todoService.getAllTodos(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Todo> getTodoById(@PathVariable Long id) {
|
||||
Optional<Todo> todo = todoService.getTodoById(id);
|
||||
return todo.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
|
||||
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Todo> createTodo(@RequestBody Todo todo) {
|
||||
Todo createdTodo = todoService.createTodo(todo);
|
||||
return new ResponseEntity<>(createdTodo, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<Todo> updateTodo(@PathVariable Long id, @RequestBody Todo todo) {
|
||||
Todo updatedTodo = todoService.updateTodo(id, todo);
|
||||
if (updatedTodo != null) {
|
||||
return new ResponseEntity<>(updatedTodo, HttpStatus.OK);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteTodo(@PathVariable Long id) {
|
||||
if (todoService.deleteTodo(id)) {
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
65
backend/src/main/java/com/todo/backend/model/Todo.java
Normal file
65
backend/src/main/java/com/todo/backend/model/Todo.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package com.todo.backend.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "todos")
|
||||
public class Todo {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String title;
|
||||
|
||||
@Column(length = 1000)
|
||||
private String description;
|
||||
|
||||
@Column(nullable = false)
|
||||
private boolean completed = false;
|
||||
|
||||
// Default constructor is required by JPA
|
||||
public Todo() {
|
||||
}
|
||||
|
||||
public Todo(String title, String description, boolean completed) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
// no setId as it's auto-generated, though sometimes needed for mapping
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted(boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.todo.backend.repository;
|
||||
|
||||
import com.todo.backend.model.Todo;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface TodoRepository extends JpaRepository<Todo, Long> {
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.todo.backend.service;
|
||||
|
||||
import com.todo.backend.model.Todo;
|
||||
import com.todo.backend.repository.TodoRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class TodoService {
|
||||
|
||||
private final TodoRepository todoRepository;
|
||||
|
||||
@Autowired
|
||||
public TodoService(TodoRepository todoRepository) {
|
||||
this.todoRepository = todoRepository;
|
||||
}
|
||||
|
||||
public List<Todo> getAllTodos() {
|
||||
return todoRepository.findAll();
|
||||
}
|
||||
|
||||
public Optional<Todo> getTodoById(Long id) {
|
||||
return todoRepository.findById(id);
|
||||
}
|
||||
|
||||
public Todo createTodo(Todo todo) {
|
||||
return todoRepository.save(todo);
|
||||
}
|
||||
|
||||
public Todo updateTodo(Long id, Todo todoDetails) {
|
||||
Optional<Todo> optionalTodo = todoRepository.findById(id);
|
||||
|
||||
if (optionalTodo.isPresent()) {
|
||||
Todo existingTodo = optionalTodo.get();
|
||||
existingTodo.setTitle(todoDetails.getTitle());
|
||||
existingTodo.setDescription(todoDetails.getDescription());
|
||||
existingTodo.setCompleted(todoDetails.isCompleted());
|
||||
return todoRepository.save(existingTodo);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean deleteTodo(Long id) {
|
||||
if (todoRepository.existsById(id)) {
|
||||
todoRepository.deleteById(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
7
backend/src/main/resources/application.properties
Normal file
7
backend/src/main/resources/application.properties
Normal file
@@ -0,0 +1,7 @@
|
||||
spring.application.name=backend
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/tododb
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=postgres
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
|
||||
Reference in New Issue
Block a user