@ -0,0 +1,25 @@ | |||||
package com.ims.rallyModels.controlador; | |||||
import com.ims.rallyModels.servicio.img.StorageService; | |||||
import jakarta.annotation.Resource; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.PathVariable; | |||||
import org.springframework.web.bind.annotation.ResponseBody; | |||||
@Controller | |||||
public class FilesController { | |||||
@Autowired | |||||
StorageService storageService; | |||||
@GetMapping("/files/{filename:.+}") | |||||
@ResponseBody | |||||
public ResponseEntity<Resource> serveFile(@PathVariable String filename) { | |||||
Resource file = (Resource) storageService.loadAsResource(filename); | |||||
return ResponseEntity.ok().body(file); | |||||
} | |||||
} |
@ -0,0 +1,52 @@ | |||||
package com.ims.rallyModels.controlador; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import com.ims.rallyModels.repositorio.IUserRepository; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.ui.Model; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
@Controller | |||||
public class LoginControlador { | |||||
@Autowired | |||||
private IUserRepository iUserRepository; | |||||
@GetMapping({"/login"}) | |||||
public String goToLogin(Model model){ | |||||
return "login"; | |||||
} | |||||
/* | |||||
@Autowired | |||||
private IUsuarioRepositorio iUserRepository; | |||||
@GetMapping({"/login"}) | |||||
public String goToLogin(Model model){ | |||||
return "login"; | |||||
} | |||||
*/ | |||||
/* | |||||
@Autowired | |||||
private IUsuarioRepositorio iUsuarioRepositorio; | |||||
@GetMapping({"/login"}) | |||||
public String goToLogin(Model model) { | |||||
return "login"; | |||||
} | |||||
@GetMapping({"/"}) | |||||
public String verPaginaInicio(Model model) { | |||||
return "index"; | |||||
} | |||||
@GetMapping("/login/valid") | |||||
public String loginValidation(String username) { | |||||
UsuarioEntity user = iUsuarioRepositorio.findByName(username); | |||||
return "login"; | |||||
} | |||||
*/ | |||||
} |
@ -0,0 +1,72 @@ | |||||
package com.ims.rallyModels.controlador; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.repositorio.IUserRepository; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.ui.Model; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
@Controller | |||||
public class RegistroControlador { | |||||
@Autowired | |||||
private IUserRepository iUserRepository; | |||||
@GetMapping({"/register"}) | |||||
public String goToregister(Model model){ | |||||
model.addAttribute("user", new UserModel()); | |||||
return "register"; | |||||
} | |||||
@PostMapping("/process_register") | |||||
public String processRegister(UserModel user) { | |||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); | |||||
String encodedPassword = passwordEncoder.encode(user.getPassword()); | |||||
user.setPassword(encodedPassword); | |||||
iUserRepository.save(user); | |||||
return "login"; | |||||
} | |||||
/*@Autowired | |||||
private IUsuarioRepositorio iUsuarioRepositorio; | |||||
//@GetMapping | |||||
//public String mostrarFormularioRegistro() { | |||||
//return "login"; | |||||
//} | |||||
/* | |||||
@PostMapping | |||||
public String registrarCuentaDeUsuario(@ModelAttribute("usuario") UsuarioRegistroDTU usuario) { | |||||
usuarioServicio.guardar(usuario); | |||||
//si logramos registrar correctamente se mandará el | |||||
//mensaje de éxito al html del registro (l.35) | |||||
return "redirect:/register?exito"; | |||||
} | |||||
@GetMapping("security/user") | |||||
public String getUser( Model model) { | |||||
CustomUserDetails currentUser = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | |||||
UsuarioEntity user = iUsuarioRepositorio.findByNombre(currentUser.getUsername()); | |||||
model.addAttribute("user", user); | |||||
return "security/user"; | |||||
} | |||||
@GetMapping({"/register"}) | |||||
public String goToregister(Model model){ | |||||
model.addAttribute("user", new UsuarioEntity()); | |||||
return "register"; | |||||
} | |||||
@PostMapping("/process_register") | |||||
public String processRegister(UsuarioEntity user) { | |||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); | |||||
String encodedPassword = passwordEncoder.encode(user.getContrasena()); | |||||
user.setContrasena(encodedPassword); | |||||
iUsuarioRepositorio.save(user); | |||||
return "index"; | |||||
}*/ | |||||
} |
@ -0,0 +1,32 @@ | |||||
package com.ims.rallyModels.controlador; | |||||
import org.springframework.stereotype.Controller; | |||||
import org.springframework.ui.Model; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.multipart.MultipartFile; | |||||
import java.io.IOException; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.nio.file.Paths; | |||||
@Controller | |||||
public class UploadController { | |||||
public static String UPLOAD_DIRECTORY = System.getProperty("user.dir") + "/uploads"; | |||||
@GetMapping("/uploadimage") public String displayUploadForm() { | |||||
return "redirect:/public/maquetas"; | |||||
} | |||||
@PostMapping("/upload") public String uploadImage(Model model, @RequestParam("image") MultipartFile file) throws IOException { | |||||
StringBuilder fileNames = new StringBuilder(); | |||||
Path fileNameAndPath = Paths.get(UPLOAD_DIRECTORY, file.getOriginalFilename()); | |||||
fileNames.append(file.getName()); | |||||
Files.write(fileNameAndPath, file.getBytes()); | |||||
model.addAttribute("msg", "Uploaded images: " + fileNames.toString()); | |||||
return "redirect:/public/maquetas"; | |||||
} | |||||
} |
@ -1,20 +0,0 @@ | |||||
package com.ims.rallyModels.controlador; | |||||
import com.ims.rallyModels.servicio.IMaquetasServicio; | |||||
import com.ims.rallyModels.servicio.IUsuarioServicio; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.ui.Model; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
public class UsuarioControlador { | |||||
@Autowired | |||||
private IUsuarioServicio servicio; | |||||
@GetMapping({"/usuarios",""}) | |||||
public String listarMaquetas(Model model) { | |||||
model.addAttribute("usuarios",servicio.listAll()); | |||||
return "usuarios"; | |||||
} | |||||
} |
@ -0,0 +1,61 @@ | |||||
package com.ims.rallyModels.dtu; | |||||
public class UsuarioRegistroDTU { | |||||
private int idUsuario; | |||||
private String nombre; | |||||
private String password; | |||||
private String sudo; | |||||
public UsuarioRegistroDTU(int idUsuario, String nombre, String password, String sudo) { | |||||
this.idUsuario = idUsuario; | |||||
this.nombre = nombre; | |||||
this.password = password; | |||||
this.sudo = sudo; | |||||
} | |||||
public UsuarioRegistroDTU(String nombre, String password, String sudo) { | |||||
this.nombre = nombre; | |||||
this.password = password; | |||||
this.sudo = sudo; | |||||
} | |||||
public UsuarioRegistroDTU(String nombre) { | |||||
this.nombre = nombre; | |||||
} | |||||
public UsuarioRegistroDTU() { | |||||
} | |||||
public int getIdUsuario() { | |||||
return idUsuario; | |||||
} | |||||
public void setIdUsuario(int idUsuario) { | |||||
this.idUsuario = idUsuario; | |||||
} | |||||
public String getNombre() { | |||||
return nombre; | |||||
} | |||||
public void setNombre(String nombre) { | |||||
this.nombre = nombre; | |||||
} | |||||
public String getContrasena() { | |||||
return password; | |||||
} | |||||
public void setContrasena(String contrasena) { | |||||
this.password = contrasena; | |||||
} | |||||
public String getSudo() { | |||||
return sudo; | |||||
} | |||||
public void setSudo(String sudo) { | |||||
this.sudo = sudo; | |||||
} | |||||
} |
@ -0,0 +1,97 @@ | |||||
package com.ims.rallyModels.modelo; | |||||
import jakarta.persistence.*; | |||||
import org.springframework.data.annotation.CreatedDate; | |||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | |||||
import java.util.Date; | |||||
import java.util.Objects; | |||||
@Entity | |||||
@EntityListeners(AuditingEntityListener.class) | |||||
public class UserModel { | |||||
@Id | |||||
@GeneratedValue | |||||
private long id; | |||||
private String email; | |||||
private String password; | |||||
private String name; | |||||
private String surname; | |||||
@CreatedDate | |||||
@Temporal(TemporalType.TIMESTAMP) | |||||
private Date createdDate; | |||||
public UserModel() { } | |||||
public UserModel(String name, String surname, String email, String password) { | |||||
this.name = name; | |||||
this.surname = surname; | |||||
this.email = email; | |||||
this.password = password; | |||||
} | |||||
public long getId() { | |||||
return id; | |||||
} | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public String getSurname() { | |||||
return surname; | |||||
} | |||||
public Date getCreatedDate() { | |||||
return createdDate; | |||||
} | |||||
public String getEmail() { | |||||
return email; | |||||
} | |||||
public String getPassword() { | |||||
return password; | |||||
} | |||||
@Override | |||||
public boolean equals(Object o) { | |||||
if (this == o) return true; | |||||
if (o == null || getClass() != o.getClass()) return false; | |||||
UserModel user = (UserModel) o; | |||||
return id == user.id && email.equals(user.email); | |||||
} | |||||
@Override | |||||
public int hashCode() { | |||||
return Objects.hash(id, email); | |||||
} | |||||
public void setPassword(String password) { | |||||
this.password = password; | |||||
} | |||||
public void setId(long id) { | |||||
this.id = id; | |||||
} | |||||
public void setEmail(String email) { | |||||
this.email = email; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public void setSurname(String surname) { | |||||
this.surname = surname; | |||||
} | |||||
public void setCreatedDate(Date createdDate) { | |||||
this.createdDate = createdDate; | |||||
} | |||||
} |
@ -0,0 +1,104 @@ | |||||
package com.ims.rallyModels.reportes; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import jakarta.servlet.ServletOutputStream; | |||||
import jakarta.servlet.http.HttpServletResponse; | |||||
import org.apache.poi.ss.usermodel.Cell; | |||||
import org.apache.poi.ss.usermodel.CellStyle; | |||||
import org.apache.poi.ss.usermodel.Row; | |||||
import org.apache.poi.xssf.usermodel.XSSFFont; | |||||
import org.apache.poi.xssf.usermodel.XSSFSheet; | |||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||||
import java.io.IOException; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
public class FacturaExporterExcel { | |||||
private XSSFWorkbook libro; | |||||
private XSSFSheet hoja; | |||||
private List<MaquetaEntity> maquetas; | |||||
public FacturaExporterExcel(List<MaquetaEntity> maquetas) { | |||||
this.maquetas = maquetas; | |||||
libro = new XSSFWorkbook(); | |||||
hoja = libro.createSheet("Maquetas"); | |||||
} | |||||
private void escribirCabeceraTabla() { | |||||
Row fila = hoja.createRow(0); | |||||
CellStyle estilo = libro.createCellStyle(); | |||||
XSSFFont fuente = libro.createFont(); | |||||
fuente.setBold(true); | |||||
fuente.setFontHeight(16); | |||||
estilo.setFont(fuente); | |||||
Cell celda = fila.createCell(0); | |||||
celda.setCellValue("Id"); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(1); | |||||
celda.setCellValue("Coche"); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(2); | |||||
celda.setCellValue("Piloto"); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(3); | |||||
celda.setCellValue("Precio"); | |||||
celda.setCellStyle(estilo); | |||||
} | |||||
public void escribirDatosDeTabla() { | |||||
int numeroFilas = 1; | |||||
CellStyle estilo = libro.createCellStyle(); | |||||
XSSFFont fuente = libro.createFont(); | |||||
fuente.setFontHeight(14); | |||||
estilo.setFont(fuente); | |||||
for (MaquetaEntity m : maquetas) { | |||||
Row fila = hoja.createRow(numeroFilas++); | |||||
Cell celda = fila.createCell(0); | |||||
celda.setCellValue(m.getIdMaqueta()); | |||||
hoja.autoSizeColumn(0); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(1); | |||||
celda.setCellValue(m.getMarca()+" "+m.getModelo()); | |||||
hoja.autoSizeColumn(1); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(2); | |||||
celda.setCellValue(m.getPiloto()); | |||||
hoja.autoSizeColumn(2); | |||||
celda.setCellStyle(estilo); | |||||
celda = fila.createCell(3); | |||||
celda.setCellValue(m.getPrecio()); | |||||
hoja.autoSizeColumn(3); | |||||
celda.setCellStyle(estilo); | |||||
} | |||||
} | |||||
public void exportar(HttpServletResponse response) throws IOException { | |||||
escribirCabeceraTabla(); | |||||
escribirDatosDeTabla(); | |||||
ServletOutputStream outputStream = response.getOutputStream(); | |||||
libro.write(outputStream); | |||||
libro.close(); | |||||
outputStream.close(); | |||||
} | |||||
} |
@ -0,0 +1,87 @@ | |||||
package com.ims.rallyModels.reportes; | |||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import com.lowagie.text.*; | |||||
import com.lowagie.text.Font; | |||||
import com.lowagie.text.pdf.PdfPCell; | |||||
import com.lowagie.text.pdf.PdfPTable; | |||||
import com.lowagie.text.pdf.PdfWriter; | |||||
import jakarta.servlet.http.HttpServletResponse; | |||||
import java.awt.*; | |||||
import java.io.IOException; | |||||
import java.util.List; | |||||
public class FacturaExporterPDF { | |||||
private List<MaquetaEntity> compra; | |||||
public FacturaExporterPDF(List<MaquetaEntity> compra) { | |||||
super(); | |||||
this.compra = compra; | |||||
} | |||||
private void escribirCabeceraDeLaTabla(PdfPTable tabla) { | |||||
PdfPCell cell = new PdfPCell(); | |||||
cell.setBackgroundColor(Color.LIGHT_GRAY); | |||||
cell.setPadding(5); | |||||
Font fuente = FontFactory.getFont(FontFactory.HELVETICA); | |||||
fuente.setColor(Color.WHITE); | |||||
cell.setPhrase(new Phrase("Id",fuente)); | |||||
tabla.addCell(cell); | |||||
cell.setPhrase(new Phrase("Coche",fuente)); | |||||
tabla.addCell(cell); | |||||
cell.setPhrase(new Phrase("Piloto",fuente)); | |||||
tabla.addCell(cell); | |||||
cell.setPhrase(new Phrase("Precio",fuente)); | |||||
tabla.addCell(cell); | |||||
} | |||||
private void escribirDatosDeLaTable(PdfPTable table) { | |||||
for (MaquetaEntity m : compra) { | |||||
table.addCell(String.valueOf(m.getIdMaqueta())); | |||||
table.addCell(m.getMarca()+" "+m.getModelo()); | |||||
table.addCell(m.getPiloto()); | |||||
table.addCell(m.getPrecio().toString()); | |||||
} | |||||
} | |||||
public void exportar(HttpServletResponse response) throws IOException { | |||||
Document documento = new Document(PageSize.A4); | |||||
PdfWriter.getInstance(documento,response.getOutputStream()); | |||||
documento.open(); | |||||
Font fuente = FontFactory.getFont(FontFactory.HELVETICA); | |||||
fuente.setColor(Color.RED); | |||||
fuente.setSize(18); | |||||
Paragraph titulo = new Paragraph("Factura de maquetas", fuente); | |||||
titulo.setAlignment(Paragraph.ALIGN_CENTER); | |||||
documento.add(titulo); | |||||
PdfPTable tabla = new PdfPTable(4); | |||||
tabla.setWidthPercentage(100); | |||||
tabla.setSpacingBefore(15); | |||||
tabla.setWidths(new float[] {1f,2.3f,2.3f,2.3f}); | |||||
tabla.setWidthPercentage(110); | |||||
escribirCabeceraDeLaTabla(tabla); | |||||
escribirDatosDeLaTable(tabla); | |||||
documento.add(tabla); | |||||
documento.close(); | |||||
} | |||||
} |
@ -0,0 +1,9 @@ | |||||
package com.ims.rallyModels.repositorio; | |||||
import com.ims.rallyModels.modelo.CocheEntity; | |||||
import jdk.jfr.Registered; | |||||
import org.springframework.data.jpa.repository.JpaRepository; | |||||
import org.springframework.stereotype.Repository; | |||||
@Repository | |||||
public interface ICocheRepositorio extends JpaRepository<CocheEntity,Integer> {} |
@ -0,0 +1,9 @@ | |||||
package com.ims.rallyModels.repositorio; | |||||
import com.ims.rallyModels.modelo.CompeticionEntity; | |||||
import org.springframework.data.jpa.repository.JpaRepository; | |||||
import org.springframework.stereotype.Repository; | |||||
@Repository | |||||
public interface ICompeticionRepositorio extends JpaRepository<CompeticionEntity, Integer> { | |||||
} |
@ -1,10 +1,11 @@ | |||||
package com.ims.rallyModels.repositorio; | package com.ims.rallyModels.repositorio; | ||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | import com.ims.rallyModels.modelo.MaquetaEntity; | ||||
import com.ims.rallyModels.modelo.UsuarioEntity; | import com.ims.rallyModels.modelo.UsuarioEntity; | ||||
import org.springframework.data.jpa.repository.JpaRepository; | import org.springframework.data.jpa.repository.JpaRepository; | ||||
import org.springframework.stereotype.Repository; | |||||
@Repository | |||||
public interface IUsuarioRepositorio extends JpaRepository<UsuarioEntity, Integer> { | |||||
import java.util.List; | |||||
public interface ICompraRepositorio extends JpaRepository<CompraEntity,Integer> { | |||||
} | } |
@ -1,8 +1,16 @@ | |||||
package com.ims.rallyModels.repositorio; | package com.ims.rallyModels.repositorio; | ||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | import com.ims.rallyModels.modelo.MaquetaEntity; | ||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import org.springframework.data.jpa.repository.JpaRepository; | import org.springframework.data.jpa.repository.JpaRepository; | ||||
import org.springframework.stereotype.Repository; | import org.springframework.stereotype.Repository; | ||||
import java.util.List; | |||||
@Repository | @Repository | ||||
public interface IMaquetasRepositorio extends JpaRepository<MaquetaEntity, Integer> { } | |||||
public interface IMaquetasRepositorio extends JpaRepository<MaquetaEntity, Integer> { | |||||
List<MaquetaEntity> findByCompra(CompraEntity c); | |||||
} |
@ -0,0 +1,12 @@ | |||||
package com.ims.rallyModels.repositorio; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import org.springframework.data.jpa.repository.JpaRepository; | |||||
import org.springframework.data.jpa.repository.Query; | |||||
import org.springframework.stereotype.Repository; | |||||
public interface IUserRepository extends JpaRepository<UserModel, Integer> { | |||||
UserModel findByEmail(String email); | |||||
} |
@ -0,0 +1,55 @@ | |||||
package com.ims.rallyModels.security; | |||||
import com.ims.rallyModels.servicio.UsuarioServicioImpl; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; | |||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | |||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | |||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |||||
import org.springframework.security.crypto.password.PasswordEncoder; | |||||
import org.springframework.security.web.SecurityFilterChain; | |||||
@Configuration | |||||
@EnableWebSecurity | |||||
public class SecurityConfig { | |||||
@Bean | |||||
public UsuarioServicioImpl userDetailsService(){ | |||||
return new UsuarioServicioImpl(); | |||||
} | |||||
@Bean | |||||
public PasswordEncoder passwordEncoder() { | |||||
return new BCryptPasswordEncoder(); | |||||
} | |||||
@Bean | |||||
public DaoAuthenticationProvider authenticationProvider() { | |||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); | |||||
authProvider.setUserDetailsService(userDetailsService()); | |||||
authProvider.setPasswordEncoder(passwordEncoder()); | |||||
return authProvider; | |||||
} | |||||
@Bean | |||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { | |||||
http | |||||
.authorizeHttpRequests() | |||||
.requestMatchers("/user").authenticated() | |||||
.anyRequest().permitAll() | |||||
.and() | |||||
.formLogin() | |||||
.usernameParameter("email") | |||||
.loginPage("/login") | |||||
.defaultSuccessUrl("/public/maquetas") | |||||
.permitAll() | |||||
.and() | |||||
.logout().logoutSuccessUrl("/login").permitAll(); | |||||
return http.build(); | |||||
} | |||||
} |
@ -1,11 +0,0 @@ | |||||
package com.ims.rallyModels.servicio; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import java.util.List; | |||||
public interface IUsuarioServicio { | |||||
public List<UsuarioEntity> listAll(); | |||||
} |
@ -0,0 +1,58 @@ | |||||
package com.ims.rallyModels.servicio; | |||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import org.springframework.security.core.GrantedAuthority; | |||||
import org.springframework.security.core.userdetails.UserDetails; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
public class UserDetailsImpl implements UserDetails { | |||||
private UserModel user; | |||||
public UserDetailsImpl(UserModel user) { | |||||
this.user = user; | |||||
} | |||||
@Override | |||||
public Collection<? extends GrantedAuthority> getAuthorities() { | |||||
return null; | |||||
} | |||||
@Override | |||||
public String getPassword() { | |||||
return user.getPassword(); | |||||
} | |||||
public UserModel getUser() { | |||||
return user; | |||||
} | |||||
@Override | |||||
public String getUsername() { | |||||
return user.getEmail(); | |||||
} | |||||
@Override | |||||
public boolean isAccountNonExpired() { | |||||
return true; | |||||
} | |||||
@Override | |||||
public boolean isAccountNonLocked() { | |||||
return true; | |||||
} | |||||
@Override | |||||
public boolean isCredentialsNonExpired() { | |||||
return true; | |||||
} | |||||
@Override | |||||
public boolean isEnabled() { | |||||
return true; | |||||
} | |||||
} |
@ -1,20 +1,51 @@ | |||||
package com.ims.rallyModels.servicio; | package com.ims.rallyModels.servicio; | ||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import com.ims.rallyModels.repositorio.IMaquetasRepositorio; | |||||
import com.ims.rallyModels.repositorio.IUsuarioRepositorio; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.repositorio.IUserRepository; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.security.core.userdetails.UserDetails; | |||||
import org.springframework.security.core.userdetails.UserDetailsService; | |||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
public class UsuarioServicioImpl implements IUsuarioServicio{ | |||||
import java.util.Collection; | |||||
import java.util.stream.Collectors; | |||||
@Service | |||||
public class UsuarioServicioImpl implements UserDetailsService { | |||||
//may cons | |||||
@Autowired | @Autowired | ||||
private IUsuarioRepositorio repositorio; | |||||
private IUserRepository userRepo; | |||||
@Override | @Override | ||||
public List<UsuarioEntity> listAll() { | |||||
return repositorio.findAll(); | |||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
UserModel user = userRepo.findByEmail(username); | |||||
if (user == null) { | |||||
throw new UsernameNotFoundException("User not found"); | |||||
} | |||||
return new UserDetailsImpl(user); | |||||
} | } | ||||
/*@Override | |||||
public UsuarioEntity buscarPorNombre(String nombre) { | |||||
return repositorio.findByName(nombre); | |||||
}*/ | |||||
/* | |||||
@Override | |||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
UsuarioEntity usuario = repositorio.findByNombre(username); | |||||
if (usuario == null) { | |||||
throw new UsernameNotFoundException("Usuario o password inválidos");; | |||||
} | |||||
return new UsuarioEntity(usuario.getNombre(), usuario.getContrasena(), mapearAutoridadesRoles(usuario.getSudo())); | |||||
}*/ | |||||
/*@Override | |||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |||||
UsuarioEntity user = repositorio.findByNombre(username); | |||||
if (user == null) { | |||||
throw new UsernameNotFoundException("User not found"); | |||||
} | |||||
return new UserDetailsImpl(user); | |||||
}*/ | |||||
} | } |
@ -0,0 +1,42 @@ | |||||
package com.ims.rallyModels.servicio.coche; | |||||
import com.ims.rallyModels.modelo.CocheEntity; | |||||
import com.ims.rallyModels.repositorio.ICocheRepositorio; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
@Service | |||||
public class CocheServicioImpl implements ICocheServicio { | |||||
@Autowired | |||||
private ICocheRepositorio repositorio; | |||||
@Override | |||||
public List<CocheEntity> listAll() { | |||||
return repositorio.findAll(); | |||||
} | |||||
@Override | |||||
public CocheEntity guardarCoche(CocheEntity maqueta) { | |||||
return repositorio.save(maqueta); | |||||
} | |||||
@Override | |||||
public CocheEntity obtenerCochePorId(Integer id) { | |||||
return repositorio.findById(id).get(); | |||||
} | |||||
@Override | |||||
public CocheEntity actualizarCoche(CocheEntity maqueta) { | |||||
//primero se busca y luego se edita y guarda | |||||
return repositorio.save(maqueta); | |||||
} | |||||
@Override | |||||
public void eliminarCoches(Integer id) { | |||||
repositorio.deleteById(id); | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
package com.ims.rallyModels.servicio.coche; | |||||
import com.ims.rallyModels.modelo.CocheEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import java.util.List; | |||||
public interface ICocheServicio { | |||||
public List<CocheEntity> listAll(); | |||||
public CocheEntity guardarCoche(CocheEntity maqueta); | |||||
public CocheEntity obtenerCochePorId(Integer id); | |||||
public CocheEntity actualizarCoche(CocheEntity maqueta); | |||||
public void eliminarCoches(Integer id); | |||||
} |
@ -0,0 +1,40 @@ | |||||
package com.ims.rallyModels.servicio.competicion; | |||||
import com.ims.rallyModels.modelo.CompeticionEntity; | |||||
import com.ims.rallyModels.repositorio.ICompeticionRepositorio; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
@Service | |||||
public class CompeticionServicioImpl implements ICompeticionService { | |||||
@Autowired | |||||
private ICompeticionRepositorio repositorio; | |||||
@Override | |||||
public List<CompeticionEntity> listAll() { | |||||
return repositorio.findAll(); | |||||
} | |||||
@Override | |||||
public CompeticionEntity guardarCompeticion(CompeticionEntity competicion) { | |||||
return repositorio.save(competicion); | |||||
} | |||||
@Override | |||||
public CompeticionEntity obtenerCompeticionPorId(Integer id) { | |||||
return repositorio.findById(id).get(); | |||||
} | |||||
@Override | |||||
public CompeticionEntity actualizarCompeticion(CompeticionEntity competicion) { | |||||
return repositorio.save(competicion); | |||||
} | |||||
@Override | |||||
public void eliminarCompeticion(Integer id) { | |||||
repositorio.deleteById(id); | |||||
} | |||||
} |
@ -0,0 +1,19 @@ | |||||
package com.ims.rallyModels.servicio.competicion; | |||||
import com.ims.rallyModels.modelo.CompeticionEntity; | |||||
import java.util.List; | |||||
public interface ICompeticionService { | |||||
public List<CompeticionEntity> listAll(); | |||||
public CompeticionEntity guardarCompeticion(CompeticionEntity competicion); | |||||
public CompeticionEntity obtenerCompeticionPorId(Integer id); | |||||
public CompeticionEntity actualizarCompeticion(CompeticionEntity competicion); | |||||
public void eliminarCompeticion(Integer id); | |||||
} |
@ -0,0 +1,71 @@ | |||||
package com.ims.rallyModels.servicio.compra; | |||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import com.ims.rallyModels.repositorio.ICompraRepositorio; | |||||
import com.ims.rallyModels.servicio.maqueta.IMaquetasServicio; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
@Service | |||||
public class CompraServicioImpl implements ICompraServicio { | |||||
@Autowired | |||||
private ICompraRepositorio repositorio; | |||||
@Autowired | |||||
IMaquetasServicio maquetasServicio; | |||||
@Override | |||||
public List<CompraEntity> listAll() { | |||||
return repositorio.findAll(); | |||||
} | |||||
@Override | |||||
public CompraEntity guardarCompra(CompraEntity compra) { | |||||
return repositorio.save(compra); | |||||
} | |||||
@Override | |||||
public CompraEntity insertar(CompraEntity c, UserModel u) { | |||||
c.setUsuario(u); | |||||
return repositorio.save(c); | |||||
} | |||||
@Override | |||||
public CompraEntity obtenerCompraPorId(Integer id) { | |||||
return repositorio.findById(id).get(); | |||||
} | |||||
@Override | |||||
public CompraEntity actualizarCompra(CompraEntity compra) { | |||||
return repositorio.save(compra); | |||||
} | |||||
@Override | |||||
public void eliminarCompra(Integer id) { | |||||
repositorio.deleteById(id); | |||||
} | |||||
@Override | |||||
public List<CompraEntity> findByPropietario(UsuarioEntity propietario) { | |||||
return null; | |||||
} | |||||
@Override | |||||
public MaquetaEntity addMaquetaCompra(MaquetaEntity p, CompraEntity c) { | |||||
p.setCompra(c); | |||||
return maquetasServicio.actualizarMaqueta(p); | |||||
} | |||||
@Override | |||||
public void addMaquetaCompraTest(MaquetaEntity p, CompraEntity c) { | |||||
c.getProductos().add(p); | |||||
} | |||||
} |
@ -0,0 +1,30 @@ | |||||
package com.ims.rallyModels.servicio.compra; | |||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.MaquetaEntity; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import java.util.List; | |||||
public interface ICompraServicio { | |||||
public List<CompraEntity> listAll(); | |||||
public CompraEntity guardarCompra(CompraEntity compra); | |||||
public CompraEntity insertar(CompraEntity c, UserModel u); | |||||
public CompraEntity obtenerCompraPorId(Integer id); | |||||
public CompraEntity actualizarCompra(CompraEntity compra); | |||||
public void eliminarCompra(Integer id); | |||||
public List<CompraEntity> findByPropietario(UsuarioEntity propietario); | |||||
public MaquetaEntity addMaquetaCompra(MaquetaEntity p, CompraEntity c); | |||||
public void addMaquetaCompraTest(MaquetaEntity p, CompraEntity c); | |||||
} |
@ -0,0 +1,168 @@ | |||||
package com.ims.rallyModels.servicio.img; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.net.MalformedURLException; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.nio.file.Paths; | |||||
import java.nio.file.StandardCopyOption; | |||||
import java.util.stream.Stream; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.core.io.Resource; | |||||
import org.springframework.core.io.UrlResource; | |||||
import org.springframework.stereotype.Service; | |||||
import org.springframework.util.FileSystemUtils; | |||||
import org.springframework.util.StringUtils; | |||||
import org.springframework.web.multipart.MultipartFile; | |||||
/** | |||||
* Implementación de un {@link StorageService} que almacena | |||||
* los ficheros subidos dentro del servidor donde se ha desplegado | |||||
* la apliacación. | |||||
* | |||||
* ESTO SE REALIZA ASÍ PARA NO HACER MÁS COMPLEJO EL EJEMPLO. | |||||
* EN UNA APLICACIÓN EN PRODUCCIÓN POSIBLEMENTE SE UTILICE | |||||
* UN ALMACÉN REMOTO. | |||||
* | |||||
* | |||||
* @author Equipo de desarrollo de Spring | |||||
* | |||||
*/ | |||||
@Service | |||||
public class FileSystemStorageService implements StorageService{ | |||||
// Directorio raiz de nuestro almacén de ficheros | |||||
private final Path rootLocation; | |||||
@Autowired | |||||
public FileSystemStorageService(StorageProperties properties) { | |||||
this.rootLocation = Paths.get(properties.getLocation()); | |||||
} | |||||
/** | |||||
* Método que almacena un fichero en el almacenamiento secundario | |||||
* desde un objeto de tipo {@link org.springframework.web.multipart#} MultipartFile | |||||
* | |||||
* Modificamos el original del ejemplo de Spring para cambiar el nombre | |||||
* del fichero a almacenar. Como lo asociamos al Empleado que se ha | |||||
* dado de alta, usaremos el ID de empleado como nombre de fichero. | |||||
* | |||||
*/ | |||||
@Override | |||||
public String store(MultipartFile file) { | |||||
String filename = null; | |||||
try { | |||||
filename = StringUtils.cleanPath(file.getResource().getURL().toString()); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
String extension = StringUtils.getFilenameExtension(filename); | |||||
String justFilename = filename.replace("."+extension, ""); | |||||
String storedFilename = System.currentTimeMillis() + "_" + justFilename + "." + extension; | |||||
try { | |||||
try (InputStream inputStream = file.getInputStream()) { | |||||
Files.copy(inputStream, this.rootLocation.resolve(storedFilename), | |||||
StandardCopyOption.REPLACE_EXISTING); | |||||
return storedFilename; | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} finally { | |||||
} | |||||
} | |||||
/** | |||||
* Método que devuelve la ruta de todos los ficheros que hay | |||||
* en el almacenamiento secundario del proyecto. | |||||
*/ | |||||
@Override | |||||
public Stream<Path> loadAll() { | |||||
try { | |||||
return Files.walk(this.rootLocation, 1) | |||||
.filter(path -> !path.equals(this.rootLocation)) | |||||
.map(this.rootLocation::relativize); | |||||
} | |||||
catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Método que es capaz de cargar un fichero a partir de su nombre | |||||
* Devuelve un objeto de tipo Path | |||||
*/ | |||||
@Override | |||||
public Path load(String filename) { | |||||
return rootLocation.resolve(filename); | |||||
} | |||||
/** | |||||
* Método que es capaz de cargar un fichero a partir de su nombre | |||||
* Devuelve un objeto de tipo Resource | |||||
*/ | |||||
@Override | |||||
public Resource loadAsResource(String filename) { | |||||
try { | |||||
Path file = load(filename); | |||||
Resource resource = new UrlResource(file.toUri()); | |||||
if (resource.exists() || resource.isReadable()) { | |||||
return resource; | |||||
} | |||||
} | |||||
catch (MalformedURLException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Método que elimina todos los ficheros del almacenamiento | |||||
* secundario del proyecto. | |||||
*/ | |||||
@Override | |||||
public void deleteAll() { | |||||
FileSystemUtils.deleteRecursively(rootLocation.toFile()); | |||||
} | |||||
/** | |||||
* Método que inicializa el almacenamiento secundario del proyecto | |||||
*/ | |||||
@Override | |||||
public void init() { | |||||
try { | |||||
Files.createDirectories(rootLocation); | |||||
} | |||||
catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
@Override | |||||
public void delete(String filename) { | |||||
String justFilename = StringUtils.getFilename(filename); | |||||
try { | |||||
Path file = load(justFilename); | |||||
Files.deleteIfExists(file); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
package com.ims.rallyModels.servicio.img; | |||||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
import org.springframework.stereotype.Service; | |||||
@Service | |||||
public class StorageProperties { | |||||
private String location = "upload-dir"; | |||||
public String getLocation() { | |||||
return location; | |||||
} | |||||
public void setLocation(String location) { | |||||
this.location = location; | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
package com.ims.rallyModels.servicio.img; | |||||
import org.springframework.core.io.Resource; | |||||
import org.springframework.stereotype.Service; | |||||
import org.springframework.web.multipart.MultipartFile; | |||||
import java.nio.file.Path; | |||||
import java.util.stream.Stream; | |||||
@Service | |||||
public interface StorageService { | |||||
void init(); | |||||
String store(MultipartFile file); | |||||
Stream<Path> loadAll(); | |||||
Path load(String filename); | |||||
Resource loadAsResource(String filename); | |||||
void delete(String filename); | |||||
void deleteAll(); | |||||
} |
@ -0,0 +1,11 @@ | |||||
package com.ims.rallyModels.servicio.userMng; | |||||
import com.ims.rallyModels.modelo.CompraEntity; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.modelo.UsuarioEntity; | |||||
import java.util.List; | |||||
public interface IUsuarioServicio { | |||||
public UserModel findByNombre(String nombre); | |||||
} |
@ -0,0 +1,24 @@ | |||||
package com.ims.rallyModels.servicio.userMng; | |||||
import com.ims.rallyModels.modelo.UserModel; | |||||
import com.ims.rallyModels.repositorio.IUserRepository; | |||||
import com.ims.rallyModels.servicio.userMng.IUsuarioServicio; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
@Service | |||||
public class UserServImpl implements IUsuarioServicio { | |||||
@Autowired | |||||
IUserRepository repositorio; | |||||
@Override | |||||
public UserModel findByNombre(String nombre) { | |||||
return null; | |||||
} | |||||
public UserModel findById(int id) { | |||||
return repositorio.findById(id).get(); | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200&display=swap'); | |||||
body { | |||||
font-family: 'Manrope', sans-serif; | |||||
background:#eee; | |||||
} | |||||
.size span { | |||||
font-size: 11px; | |||||
} | |||||
.color span { | |||||
font-size: 11px; | |||||
} | |||||
.product-deta { | |||||
margin-right: 70px; | |||||
} | |||||
.gift-card:focus { | |||||
box-shadow: none; | |||||
} | |||||
.pay-button { | |||||
color: #fff; | |||||
} | |||||
.pay-button:hover { | |||||
color: #fff; | |||||
} | |||||
.pay-button:focus { | |||||
color: #fff; | |||||
box-shadow: none; | |||||
} | |||||
.text-grey { | |||||
color: #a39f9f; | |||||
} | |||||
.qty i { | |||||
font-size: 11px; | |||||
} |
@ -1,56 +0,0 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
</head> | |||||
<body> | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> | |||||
<br/> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-lg-6 col-md-6 col-sm-6 container justify-content-center card"> | |||||
<h1 class="text-center">Nueva Maqueta</h1> | |||||
<div class="card-body"> | |||||
<form th:action="@{/maquetas}" th:object="${maqueta}" method="post"> | |||||
<!-- la maqueta de th:object es la que le pasamos al controlador OJO LAS "s" --> | |||||
<div class="form-group"> | |||||
<label>Descripcion: </label> | |||||
<input type="text" name="descripcion" th:field="*{descripcion}" | |||||
class="form-control" placeholder="Descripción de la maqueta: " required> | |||||
</div> | |||||
<br/> | |||||
<div class="form-group"> | |||||
<label>Precio: </label> | |||||
<input type="number" name="precio" th:field="*{precio}" | |||||
class="form-control" placeholder="Precio de la maqueta: " required> | |||||
</div> | |||||
<br/> | |||||
<div class="box-footer"> | |||||
<button class="btn btn-success">Guardar</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -1,13 +1,37 @@ | |||||
<!DOCTYPE html> | <!DOCTYPE html> | ||||
<html> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<html lang="en" | |||||
xmlns="http://www.w3.org/1999/xhtml" | |||||
xmlns:th="http://www.thymeleaf.org" > | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"> | |||||
<head> <!--th:replace="~{/fragments/head/head}">--> | |||||
</head> | </head> | ||||
<body> | |||||
<header th:replace="~{utils/nav}"> <!--th:replace="~{/fragments/header/headerOne}"--></header> | |||||
<body class="topspace"> | |||||
<div class="imgBoxs"> | |||||
<a href="/login">login</a> | |||||
<br> | |||||
<a href="/register">register</a> | |||||
<div class="container"> | |||||
<div class="btn-group" role="group" aria-label="Basic mixed styles example"> | |||||
<a type="button" class="btn btn-success" href="/login">Inicio de sesión</a> | |||||
<a type="button" class="btn btn-danger" href="/register">Registro</a> | |||||
</div> | |||||
</div> | |||||
<p>INDEX HTML!</p> | |||||
<h1>Lista de maquetas</h1> | |||||
<a href="maqueta.html">Añadir Maqueta</a> | |||||
</div> | |||||
<br> | |||||
<br> | |||||
<br> | |||||
<br> | |||||
<br> | |||||
<br> | |||||
</body> | </body> | ||||
<!--<footer th:replace="~{/fragments/footer/footerOne}" ></footer>--> | |||||
</html> | </html> |
@ -0,0 +1,95 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en" style="background: aqua"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
<title>Login</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" | |||||
rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"> | |||||
</head> | |||||
<body style="height: 50%; width: 100%; background: aqua"> | |||||
<div class="container"> | |||||
<img src="../static/raw/circLogo.png" style="display: block; | |||||
margin-top: 5%; | |||||
margin-left: auto; | |||||
margin-right: auto; | |||||
width: 25%;" alt="logo"> | |||||
</div> | |||||
<main style="height: 100%; width: 100%"> | |||||
<!-- | |||||
<article> | |||||
<section class="vh-100 gradient-custom"> | |||||
<div class="container py-5 h-100"> | |||||
<div class="row d-flex justify-content-center align-items-center h-100"> | |||||
<div class="col-12 col-md-8 col-lg-6 col-xl-5"> | |||||
<div class="card bg-dark text-white" style="border-radius: 1rem;"> | |||||
<div class="card-body p-5 text-center"> | |||||
<div class="mb-md-5 mt-md-4 pb-5"> | |||||
<h2 class="fw-bold mb-2 text-uppercase">Inicio de sesión</h2> | |||||
<p class="text-white-50 mb-5">Introduce tu nombre y contraseña</p> | |||||
<div class="form-outline form-white mb-4"> | |||||
<input type="email" id="typeEmailX" class="form-control form-control-lg" /> | |||||
<label class="form-label" for="loginform">Nombre</label> | |||||
</div> | |||||
<div class="form-outline form-white mb-4"> | |||||
<input type="password" id="typePasswordX" class="form-control form-control-lg" /> | |||||
<label class="form-label" for="typePasswordX">Contraseña</label> | |||||
</div> | |||||
<button class="btn btn-outline-light btn-lg px-5" type="submit">Iniciar Sesión</button> | |||||
<div class="d-flex justify-content-center text-center mt-4 pt-1"> | |||||
<a href="#" class="text-white"><i class="fab fa-facebook-f fa-lg"></i></a> | |||||
<a href="#" class="text-white"><i class="fab fa-twitter fa-lg mx-4 px-2"></i></a> | |||||
<a href="#" class="text-white"><i class="fab fa-google fa-lg"></i></a> | |||||
</div> | |||||
</div> | |||||
<div> | |||||
<p class="mb-0">Don't have an account? <a href="#!" class="text-white-50 fw-bold">Sign Up</a> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</section> | |||||
</article> | |||||
--> | |||||
<div class="container" style="margin-top: 5%; border-radius: 3%; height: 20%; | |||||
background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);"> | |||||
<form id="loginform" th:action="@{/login}" method="post" role="form"> | |||||
<div class="form-group"> | |||||
<h2 for="email" style="color: #f2f2f2">Nombre Usuario</h2> | |||||
<input type="text" name="email" id="email" | |||||
class="form-control" aria-describedby="emailHelp" placeholder="Enter email"> | |||||
<small id="emailHelp" class="form-text text-muted"></small> | |||||
</div> | |||||
<div class="form-group"> | |||||
<h2 for="password" style="color: #f2f2f2">Contraseña</h2> | |||||
<input style="margin-bottom: 1%" type="password" name="password" class="form-control" id="password" placeholder="Password"> | |||||
</div> | |||||
<small class="text-muted"><a href="/register">No estas registrado?</a></small> | |||||
<button type="submit" class="btn btn-primary" style="color: #f2f2f2">Submit</button> | |||||
</form> | |||||
</div> | |||||
<!-- | |||||
<form id="loginform" th:action="@{/login}" method="POST" role="form" > | |||||
<h1>Login</h1> | |||||
<input type="text" name="email" id="email" placeholder="Email"> | |||||
<br> | |||||
<input type="password" name="password" id="password" placeholder="Password"> | |||||
<hr> | |||||
<button type="submit">Continue</button> | |||||
<small class="text-muted"><a href="/auth/register">Register here!</a></small> | |||||
</form>--> | |||||
</main> | |||||
</body> | |||||
</html> |
@ -1,76 +0,0 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
</head> | |||||
<body> | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<h1>Lista Maquetas</h1> | |||||
</div> | |||||
<table class="table table-striped table-bordered"> | |||||
<thead class="table-dark"> | |||||
<tr> | |||||
<th>Descripcion</th> | |||||
<th>Coche</th> | |||||
<th>Competicion</th> | |||||
<th>Precio</th> | |||||
<th>Acciones</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr th:each="maqueta : ${maquetas}">. | |||||
<td th:text="${maqueta.descripcion}">Descripcion</td> | |||||
<td th:text="${maqueta.fkIdCoche}">Coche</td> | |||||
<td th:text="${maqueta.fkIdCompeticion}">Competicion</td> | |||||
<td th:text="${maqueta.precio}">Precio</td> | |||||
<td> | |||||
<a th:href="@{/maquetas/editar/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-info">Editar</a> | |||||
<a th:href="@{/maquetas/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-danger">Eliminar</a> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<div class="container"> | |||||
<div class="card" style="width: 18rem;"> | |||||
<img src="raw/images.jfif" class="card-img-top" alt="..."> | |||||
<div class="card-body"> | |||||
<h5 class="card-title">Card title</h5> | |||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> | |||||
<a href="#" class="btn btn-primary">Go somewhere</a> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,57 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en" | |||||
xmlns:th="http://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>Title</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
<link href="/static/css/shoppingCart.css" rel="stylesheet" /> | |||||
</head> | |||||
<header th:replace="~{utils/nav}"></header> | |||||
<body> | |||||
<div class="container mt-5 mb-5"> | |||||
<div class="d-flex justify-content-center row"> | |||||
<div class="col-md-8"> | |||||
<div class="p-2"> | |||||
<h4>Carrito de la Compra</h4> | |||||
</div> | |||||
<div th:if="${carrito == null}"> | |||||
<div class="col-md-offset-1 col-md-10"> | |||||
<div class="jumbotron"> | |||||
<div class="container"> | |||||
<h2 class="text-center">Aún no ha seleccionado ningún producto para comprar</h2> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<th:block th:each="producto : ${carrito}"> | |||||
<div class="d-flex flex-row justify-content-between align-items-center p-2 bg-white mt-4 px-3 rounded"> | |||||
<div class="mr-1"><img class="rounded" th:src="@{${producto.image}}" width="70" alt="Imagen de la maqueta" /></div> | |||||
<div class="d-flex flex-column align-items-center product-details"><span class="font-weight-bold" th:text="${producto.piloto}">Maqueta</span> | |||||
<div class="d-flex flex-row product-desc"> | |||||
<div class="size mr-1"><span class="text-grey" th:text="${producto.marca+' '}">Marca del Coche:</span> | |||||
<span class="font-weight-bold"></span> | |||||
</div> | |||||
<div class="color"><span class="text-grey" th:text="${producto.modelo}">Modelo del Coche:</span> | |||||
<span class="font-weight-bold"></span> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div> | |||||
<h5 class="text-grey" th:text="${producto.precio}">$20.00</h5> | |||||
</div> | |||||
<a type="button" class="btn btn-danger" th:href="@{/public/carrito/eliminar/{id}(id=${producto.idMaqueta})}">Eliminar</a> | |||||
<div class="d-flex align-items-center"><i class="fa fa-trash mb-1 text-danger"></i></div> | |||||
</div> | |||||
</th:block> | |||||
<h5>Precio Total: <a th:text="${#numbers.formatCurrency(total_carrito)}"></a></h5> | |||||
<div class="d-flex flex-row align-items-center mt-3 p-2 bg-white rounded"> | |||||
<a th:href="@{/public/carrito/finalizar}" class="btn btn-warning btn-block btn-lg ml-2 pay-button" type="button">Procesar Compra</a> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,89 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
</head> | |||||
<body> | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/public/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> | |||||
<br/> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-lg-6 col-md-6 col-sm-6 container justify-content-center card"> | |||||
<h1 class="text-center">Nueva Maqueta</h1> | |||||
<div class="card-body"> | |||||
<form th:action="@{/public/maquetas}" th:object="${maqueta}" method="post"> | |||||
<!-- la maqueta de th:object es la que le pasamos al controlador OJO LAS "s" --> | |||||
<div class="form-group"> | |||||
<label>Piloto: </label> | |||||
<input type="text" name="piloto" th:field="*{piloto}" | |||||
class="form-control" placeholder="Piloto: " required> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label>Marca: </label> | |||||
<input type="text" name="marca" th:field="*{marca}" | |||||
class="form-control" placeholder="Marca: " required> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label>Modelo del coche: </label> | |||||
<input type="text" name="modelo" th:field="*{modelo}" | |||||
class="form-control" placeholder="Modelo: " required> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label>Competicion: </label> | |||||
<input type="number" name="modelo" th:field="*{competicion}" | |||||
class="form-control" placeholder="Competicion: " required> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label>Precio: </label> | |||||
<input type="text" name="precio" th:field="*{precio}" | |||||
class="form-control" placeholder="Precio de la maqueta: " required> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label>Descripcion: </label> | |||||
<input type="text" name="descripcion" th:field="*{descripcion}" | |||||
class="form-control" placeholder="Descripción de la maqueta: " required> | |||||
</div> | |||||
<!--<div class="form-group"> | |||||
<label>Imagen</label> <input id="filebutton" name="file" class="form-control input-file" type="file"> | |||||
</div> | |||||
<div class="col-md-8 mx-auto"> | |||||
<h2>Upload Image Example</h2> | |||||
<p th:text="${message}" th:if="${message ne null}" class="alert alert-primary"></p> | |||||
<form method="post" th:action="@{/upload}" enctype="multipart/form-data"> | |||||
<div class="form-group"> | |||||
<input type="file" name="image" accept="image/*" class="form-control-file"> | |||||
</div> | |||||
<button type="submit" class="btn btn-primary">Upload image</button> | |||||
</form> | |||||
<span th:if="${msg != null}" th:text="${msg}"></span> | |||||
</div> | |||||
<br/>--> | |||||
<div class="box-footer"> | |||||
<button class="btn btn-success">Guardar</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,79 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>Title</title> | |||||
</head> | |||||
<body> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-xs-offset-3 col-xs-6"> | |||||
<div class="invoice-title"> | |||||
<h2>Factura</h2> | |||||
<h3 class="pull-right"> | |||||
Compra #<span th:text="${compra.idCompra}">1234</span> | |||||
</h3> | |||||
</div> | |||||
<hr> | |||||
<div class="row"> | |||||
<!--<div class="col-xs-6"> | |||||
<address> | |||||
<strong>Comprado por:</strong><br> <span | |||||
th:text="${compra.getUsuario().name + ' ' + compra.getUsuario().surname}"></span><br> | |||||
<span th:text="${compra.getUsuario().email}"></span><br> | |||||
</address> | |||||
</div> | |||||
<div class="col-xs-6 text-right"> | |||||
<address> | |||||
<strong>Fecha de compra:</strong><br> <span | |||||
th:text="${#dates.format(compra.fecha,'dd/MMM/yyyy HH:mm')}"></span><br> | |||||
<br> | |||||
</address> | |||||
</div>--> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-md-offset-3 col-md-6"> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title"> | |||||
<strong>Listado de productos</strong> | |||||
</h3> | |||||
</div> | |||||
<div class="panel-body invoice-body"> | |||||
<div class="table-responsive"> | |||||
<table class="table table-condensed"> | |||||
<thead> | |||||
<tr> | |||||
<td><strong>Producto</strong></td> | |||||
<td class="text-right"><strong>Precio</strong></td> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr th:each="producto : ${productos}"> | |||||
<td><span th:text="${producto.marca+' '+producto.modelo}">Producto</span></td> | |||||
<td class="text-right"><span th:text="${#numbers.formatCurrency(producto.precio)}">123€</span></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="thick-line text-right"><strong>Total</strong></td> | |||||
<td class="thick-line text-right"><span | |||||
th:text="${#numbers.formatCurrency(total_compra)}"></span></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<div class="d-flex flex-row align-items-center mt-3 p-2 bg-white rounded"> | |||||
<a th:href="@{/public/exportarExcel/{id}(id=${compra.getIdCompra()})}" class="btn btn-warning btn-block btn-lg ml-2 pay-button" type="button">Obtener Factura Excel</a> | |||||
</div> | |||||
<div class="d-flex flex-row align-items-center mt-3 p-2 bg-white rounded"> | |||||
<a th:href="@{/public/exportarPDF/{id}(id=${compra.getIdCompra()})}" class="btn btn-warning btn-block btn-lg ml-2 pay-button" type="button">Obtener Factura PDF</a> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,7 @@ | |||||
/*! | |||||
* Start Bootstrap - Shop Item v5.0.5 (https://startbootstrap.com/template/shop-item) | |||||
* Copyright 2013-2022 Start Bootstrap | |||||
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-shop-item/blob/master/LICENSE) | |||||
*/ | |||||
// This file is intentionally blank | |||||
// Use this file to add JavaScript to your project |
@ -0,0 +1,125 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
</head> | |||||
<body> | |||||
<nav class="navbar navbar-expand-lg bg-dark navbar-dark"> | |||||
<div class="container-fluid"> | |||||
<a class="navbar-brand" href="#">Rally Models</a> | |||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" | |||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> | |||||
<span class="navbar-toggler-icon"></span> | |||||
</button> | |||||
<div class="collapse navbar-collapse" id="navbarSupportedContent"> | |||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0"> | |||||
<li class="nav-item"> | |||||
<a class="nav-link active" aria-current="page" th:href="@{/public/maquetas}">Home</a> | |||||
</li> | |||||
<li class="nav-item"> | |||||
<a class="nav-link" href="#">Control de maquetas</a> | |||||
</li> | |||||
<li class="nav-item"> | |||||
<a th:href="@{/logout}" method="POST" id="logoutForm">Cerrar Sesion</a> | |||||
</li> | |||||
</ul> | |||||
<a th:href="@{/public/maquetas/nuevo}" | |||||
class="btn btn-primary btn-sm mb3">Agregar Maqueta</a> | |||||
<a th:href="@{/public/carrito}" | |||||
class="btn btn-primary btn-sm mb3">Ver Carrito</a> | |||||
</div> | |||||
</div> | |||||
</nav> | |||||
<!-- | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> | |||||
--> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<h1>Lista Maquetas</h1> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-lg-3"> | |||||
<a th:href="@{/public/maquetas/nuevo}" | |||||
class="btn btn-primary btn-sm mb3">Agregar Maqueta</a> | |||||
</div> | |||||
</div> | |||||
<br /> | |||||
<table class="table table-striped table-bordered"> | |||||
<thead class="table-dark"> | |||||
<tr> | |||||
<th>Descripcion</th> | |||||
<th>Coche</th> | |||||
<th>Competicion</th> | |||||
<th>Precio</th> | |||||
<th>Acciones</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr th:each="maqueta : ${maquetas}"> | |||||
<td th:text="${maqueta.getPiloto()}">Descripcion</td> | |||||
<td th:text="${maqueta.getMarca()+maqueta.getModelo()}">Coche</td> | |||||
<td th:text="${maqueta.getCompeticion().getNombre()}">Competicion</td> | |||||
<td th:text="${maqueta.getPrecio()}">Precio</td> | |||||
<td> | |||||
<a th:href="@{/public/maquetas/editar/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-info">Editar</a> | |||||
<a th:href="@{/public/maquetas/eliminar/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-danger">Eliminar</a> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<th:block th:each="maqueta : ${maquetas}"> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="card" style="width: 18rem; margin: auto"> | |||||
<img th:src="@{${maqueta.getImage()}}" class="card-img-top" alt="fordPuma"> | |||||
<div class="card-body" style=""> | |||||
<h5 class="card-title" th:text="${maqueta.getMarca()+maqueta.getModelo()}" /> | |||||
<input type="hidden" name="selectedElementName" th:value="${maqueta.getCompeticion().getNombre()}" /> | |||||
<p class="card-text" th:text="${maqueta.getPiloto()}" /> | |||||
<p class="card-text" th:text="${maqueta.getPrecio()}" style="text-align: right"/> | |||||
<!--<button class="btn btn-primary form-control" type="submit">Enter</button>--> | |||||
</div> | |||||
<!--<ul th:each="maqueta : ${maquetas}"> | |||||
<li th:text="${maqueta.getCoche().getPiloto()}">Piloto</li> | |||||
<li th:text="${maqueta.getCoche().getMarca()}">Marca</li> | |||||
<li th:text="${maqueta.getCoche().getModelo()}">Modelo</li> | |||||
</ul> | |||||
<h5 class="card-title" ></h5> | |||||
<h5 class="card-title" ></h5> | |||||
<h5 class="card-title"></h5>--> | |||||
<a th:href="@{/public/maquetas/mostrar/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-primary">Detalles</a> | |||||
<a th:href="@{/public/carrito/add/{id}(id=${maqueta.idMaqueta})}" class="btn btn-primary">Añadir al carrito</a> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</th:block> | |||||
</body> | |||||
</html> |
@ -0,0 +1,47 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en" xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> | |||||
<title>Detalles de la maqueta</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" /> | |||||
<link href="/static/css/styles.css" rel="stylesheet" /> | |||||
</head> | |||||
<header th:replace="~{utils/nav}"></header> | |||||
<body> | |||||
<section class="py-5"> | |||||
<div class="container px-4 px-lg-5 my-5"> | |||||
<div class="row gx-4 gx-lg-5 align-items-center"> | |||||
<div class="col-md-6"><img class="card-img-top mb-5 mb-md-0" th:src="@{${maqueta.image}}" alt="Foto de la Maqueta" /></div> | |||||
<div class="col-md-6"> | |||||
<div> | |||||
<div class="small mb-1" th:text="${maqueta.piloto}">Piloto</div> | |||||
<h1 class="display-5 fw-bolder" th:text="${maqueta.marca+' '+maqueta.modelo}">Maqueta</h1> | |||||
<div class="fs-5 mb-5"> | |||||
<span th:text="${maqueta.precio}+'€'">$40.00</span> | |||||
</div> | |||||
<p class="lead" th:text="${maqueta.descripcion}">Descripcion</p> | |||||
<div class="d-flex"> | |||||
<input class="form-control text-center me-3" id="inputQuantity" type="num" value="1" style="max-width: 3rem" /> | |||||
<button th:href="@{/public/carrito/add/{id}(id=${maqueta.idMaqueta})}" class="btn btn-outline-dark flex-shrink-0" type="button"><!-- OJO --> | |||||
<i class="bi-cart-fill me-1"></i> | |||||
Añadir al carrito | |||||
</button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</section> | |||||
<!-- Footer--> | |||||
<footer class="py-5 bg-dark"> | |||||
<div class="container"><p class="m-0 text-center text-white">Copyright © Rally Models Corp. 2023</p></div> | |||||
</footer> | |||||
<!-- Bootstrap core JS--> | |||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> | |||||
<!-- Core theme JS--> | |||||
<script src="js/scripts.js"></script> | |||||
</body> | |||||
</html> |
@ -0,0 +1,25 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en" | |||||
xmlns:th="http://www.w3.org/1999/xhtml" | |||||
xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>Register</title> | |||||
</head> | |||||
<body> | |||||
<main> | |||||
<!--<form id="registerform" th:action="@{/process_register}" th:object="${user}" method="POST" role="form" > | |||||
<h1>Register</h1> | |||||
<input type="text" th:field="*{email}" placeholder="Email"> | |||||
<br> | |||||
<input type="text" th:field="*{name}" placeholder="Username"> | |||||
<br> | |||||
<input type="text" th:field="*{surname}" placeholder="Surname"> | |||||
<br> | |||||
<input type="password" th:field="*{password}" placeholder="Password"> | |||||
<hr> | |||||
<button type="submit">Continue</button> | |||||
</form>--> | |||||
</main> | |||||
</body> | |||||
</html> |
@ -0,0 +1,72 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="https://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>RallyModels</title> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" | |||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
</head> | |||||
<body> | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<h1>Lista Maquetas</h1> | |||||
</div> | |||||
<div class="row"> | |||||
<div class="col-lg-3"> | |||||
<a th:href="@{/maquetas/nuevo}" | |||||
class="btn btn-primary btn-sm mb3">Agregar Maqueta</a> | |||||
</div> | |||||
</div> | |||||
<br /> | |||||
<table class="table table-striped table-bordered"> | |||||
<thead class="table-dark"> | |||||
<tr> | |||||
<th>Descripcion</th> | |||||
<th>Coche</th> | |||||
<th>Competicion</th> | |||||
<th>Precio</th> | |||||
<th>Acciones</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr th:each="maqueta : ${maquetas}">. | |||||
<td th:text="${maqueta.descripcion}">Descripcion</td> | |||||
<td th:text="${maqueta.fkIdCoche}">Coche</td> | |||||
<td th:text="${maqueta.fkIdCompeticion}">Competicion</td> | |||||
<td th:text="${maqueta.precio}">Precio</td> | |||||
<td> | |||||
<a th:href="@{/maquetas/editar/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-info">Editar</a> | |||||
<a th:href="@{/maquetas/{id}(id=${maqueta.idMaqueta})}" | |||||
class="btn btn-danger">Eliminar</a> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,111 @@ | |||||
<!DOCTYPE html> | |||||
<html xmlns:th="http://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<title>Registro de usuarios</title> | |||||
<!-- Latest compiled and minified CSS --> | |||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"> | |||||
</head> | |||||
<header th:replace="~{/utils/nav}"></header> | |||||
<body> | |||||
<div class="container" style="margin-top: 5%; height: 20%; | |||||
background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);"> | |||||
<form id="loginform" th:action="@{/process_register}" th:object="${user}" method="post" role="form"> | |||||
<h1>Registro</h1> | |||||
<div class="form-group"> | |||||
<h2 for="email" style="color: #f2f2f2">Email</h2> | |||||
<input type="email" th:field="*{email}" placeholder="Email"> | |||||
<small id="emailHelp" class="form-text text-muted"></small> | |||||
</div> | |||||
<div class="form-group"> | |||||
<h2 for="name" style="color: #f2f2f2">Nombre</h2> | |||||
<input type="text" th:field="*{name}" placeholder="Name"> | |||||
<small id="name" class="form-text text-muted"></small> | |||||
</div> | |||||
<div class="form-group"> | |||||
<h2 for="surname" style="color: #f2f2f2">Apellido</h2> | |||||
<input type="text" th:field="*{surname}" placeholder="Surname"> | |||||
<small id="surname" class="form-text text-muted"></small> | |||||
</div> | |||||
<div class="form-group"> | |||||
<h2 for="password" style="color: #f2f2f2">Contraseña</h2> | |||||
<input style="margin-bottom: 1%" type="password" th:field="*{password}" placeholder="Password"> | |||||
</div> | |||||
<small class="text-muted"><a href="/register">No estas registrado?</a></small> | |||||
<button type="submit" class="btn btn-primary" style="color: #f2f2f2">Submit</button> | |||||
</form> | |||||
</div> | |||||
<!-- | |||||
<main> | |||||
<form id="registerform" th:action="@{/process_register}" th:object="${user}" method="POST" role="form" > | |||||
<h1>Register</h1> | |||||
<input type="text" th:field="*{email}" placeholder="Username"> | |||||
<br> | |||||
<input type="password" th:field="*{password}" placeholder="Password"> | |||||
<hr> | |||||
<button type="submit">Continue</button> | |||||
</form> | |||||
</main> | |||||
--> | |||||
</body> | |||||
</html> | |||||
<!-- | |||||
<div class="container"> | |||||
<div class="row"> | |||||
<div class="col-md-6 col-md-offset-3"> | |||||
<div th:if="${param.exito}"> | |||||
<div class="alert alert-info">Se ha registrado exitosamente a | |||||
la aplicación | |||||
</div> | |||||
</div> | |||||
<h1>Regístrate</h1> | |||||
<form th:action="@{/registro}" method="post" th:object="${usuario}"> | |||||
<form th:action="@{/process_register}" method="post" th:object="${user}" role=""form> | |||||
<div class="form-group"> | |||||
<label class="control-label" for="nombre">Nombre : </label> <input | |||||
id="nombre" type="text" class="form-control" th:field="*{nombre}" | |||||
required autofocus="autofocus"> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label class="control-label" for="password">Password : </label> <input | |||||
type="password" id="password" class="form-control" th:field="*{contrasena}" | |||||
required autofocus="autofocus"> | |||||
</div> | |||||
<div class="form-group"> | |||||
<button type="submit" class="btn btn-success">Registrar</button> | |||||
<span>Si estas registrado <a th:href="@{/login}">inicia sesión aqui</a></span> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div>--> | |||||
<!-- Latest compiled and minified JavaScript --> | |||||
<script | |||||
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" | |||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" | |||||
crossorigin="anonymous"></script> | |||||
</body> | |||||
</html> | |||||
@ -0,0 +1,9 @@ | |||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark"> | |||||
<a class="navbar-brand" href="#">Control de Maquetas</a> | |||||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> | |||||
<ul class="navbar-nav"> | |||||
<li class="nav-item"><a class="nav-link" | |||||
th:href="@{/public/maquetas}">Control de maquetas</a> </li> | |||||
</ul> | |||||
</div> | |||||
</nav> |