commit e37b1b2596cae3fee2cae0f7fa2b09c8271bf847 Author: Tatiana Villa Ema Date: Sun May 24 00:25:10 2026 +0200 first commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..06e23a9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.gradle/ +build/ +.git/ +.gitignore +*.md +.idea/ +*.iml +out/ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7a7da9a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +# ── Etapa 1: build ────────────────────────────────────────────── +FROM eclipse-temurin:17-jdk-alpine AS build +WORKDIR /app + +# Copiamos wrapper y descriptores primero (cache de capas) +COPY gradlew gradlew.bat ./ +COPY gradle/ gradle/ +COPY build.gradle settings.gradle ./ + +# Descargamos dependencias sin copiar aún el código fuente +RUN chmod +x gradlew && ./gradlew dependencies --no-daemon -q || true + +# Ahora copiamos el código y construimos el jar +COPY src/ src/ +RUN ./gradlew bootJar -x test --no-daemon + +# ── Etapa 2: runtime ───────────────────────────────────────────── +FROM eclipse-temurin:17-jre-alpine +WORKDIR /app + +# Usuario no root por seguridad +RUN addgroup -S oracion && adduser -S oracion -G oracion +USER oracion + +COPY --from=build /app/build/libs/*.jar app.jar + +EXPOSE 8080 + +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..68ab94c --- /dev/null +++ b/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '4.0.6' + id 'io.spring.dependency-management' version '1.1.7' +} + +group = 'es.tatvil' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.fasterxml.jackson.core:jackson-databind' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' + implementation 'com.fasterxml.jackson.core:jackson-databind' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + runtimeOnly 'com.mysql:mysql-connector-j' + runtimeOnly 'com.h2database:h2' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..44a0968 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +services: + + db: + image: mysql:8.4 + container_name: oracion-db + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-oracion_secret} + MYSQL_DATABASE: oracion_db + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${DB_ROOT_PASSWORD:-oracion_secret}"] + interval: 10s + timeout: 5s + retries: 10 + + app: + build: . + container_name: oracion-app + restart: unless-stopped + ports: + - "8081:8080" + environment: + SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/oracion_db?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=Europe/Madrid&allowPublicKeyRetrieval=true + SPRING_DATASOURCE_USERNAME: root + SPRING_DATASOURCE_PASSWORD: ${DB_ROOT_PASSWORD:-oracion_secret} + SPRING_JPA_HIBERNATE_DDL_AUTO: update + SPRING_THYMELEAF_CACHE: "true" + depends_on: + db: + condition: service_healthy + +volumes: + mysql_data: diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d997cfc Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..c61a118 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..739907d --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..22c0f39 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'oracion' diff --git a/src/main/java/es/tatvil/oracion/OracionApplication.java b/src/main/java/es/tatvil/oracion/OracionApplication.java new file mode 100644 index 0000000..a869f08 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/OracionApplication.java @@ -0,0 +1,13 @@ +package es.tatvil.oracion; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OracionApplication { + + public static void main(String[] args) { + SpringApplication.run(OracionApplication.class, args); + } + +} diff --git a/src/main/java/es/tatvil/oracion/config/SecurityConfig.java b/src/main/java/es/tatvil/oracion/config/SecurityConfig.java new file mode 100644 index 0000000..3a09bfe --- /dev/null +++ b/src/main/java/es/tatvil/oracion/config/SecurityConfig.java @@ -0,0 +1,39 @@ +package es.tatvil.oracion.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +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 PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(auth -> auth + .requestMatchers("/", "/login", "/registro", "/css/**", "/js/**", "/images/**").permitAll() + .anyRequest().authenticated() + ) + .formLogin(form -> form + .loginPage("/login") + .usernameParameter("email") + .defaultSuccessUrl("/inicio", true) + .permitAll() + ) + .logout(logout -> logout + .logoutSuccessUrl("/?logout") + .permitAll() + ); + return http.build(); + } +} diff --git a/src/main/java/es/tatvil/oracion/diario/Diario.java b/src/main/java/es/tatvil/oracion/diario/Diario.java new file mode 100644 index 0000000..cccded2 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/diario/Diario.java @@ -0,0 +1,37 @@ +package es.tatvil.oracion.diario; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Table(name = "diario_entradas") +@Data +@NoArgsConstructor +public class Diario { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String titulo; + + @Column(nullable = false, columnDefinition = "TEXT") + private String contenido; + + @Column(nullable = false) + private LocalDate fecha; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "usuario_id", nullable = false) + private Usuario usuario; + + @PrePersist + public void prePersist() { + if (fecha == null) fecha = LocalDate.now(); + } +} diff --git a/src/main/java/es/tatvil/oracion/diario/DiarioController.java b/src/main/java/es/tatvil/oracion/diario/DiarioController.java new file mode 100644 index 0000000..98c7f7e --- /dev/null +++ b/src/main/java/es/tatvil/oracion/diario/DiarioController.java @@ -0,0 +1,73 @@ +package es.tatvil.oracion.diario; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +@Controller +@RequestMapping("/diario") +@RequiredArgsConstructor +public class DiarioController { + + private final DiarioService diarioService; + + @GetMapping + public String lista(Model model, @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("entradas", diarioService.listarPorUsuario(usuario)); + return "diario/lista"; + } + + @GetMapping("/nueva") + public String nuevaForm(Model model) { + model.addAttribute("entrada", new Diario()); + return "diario/nueva"; + } + + @PostMapping("/nueva") + public String guardar(@Valid @ModelAttribute("entrada") Diario diario, + BindingResult result, + @AuthenticationPrincipal Usuario usuario) { + if (result.hasErrors()) return "diario/nueva"; + diarioService.guardar(diario, usuario); + return "redirect:/diario"; + } + + @GetMapping("/{id}") + public String ver(@PathVariable Long id, Model model, + @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("entrada", diarioService.buscarPorIdYUsuario(id, usuario)); + return "diario/ver"; + } + + @GetMapping("/{id}/editar") + public String editarForm(@PathVariable Long id, Model model, + @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("entrada", diarioService.buscarPorIdYUsuario(id, usuario)); + return "diario/nueva"; + } + + @PostMapping("/{id}/editar") + public String actualizar(@PathVariable Long id, + @Valid @ModelAttribute("entrada") Diario diario, + BindingResult result, + @AuthenticationPrincipal Usuario usuario) { + if (result.hasErrors()) return "diario/nueva"; + Diario existente = diarioService.buscarPorIdYUsuario(id, usuario); + existente.setTitulo(diario.getTitulo()); + existente.setContenido(diario.getContenido()); + existente.setFecha(diario.getFecha()); + diarioService.guardar(existente, usuario); + return "redirect:/diario"; + } + + @PostMapping("/{id}/eliminar") + public String eliminar(@PathVariable Long id, @AuthenticationPrincipal Usuario usuario) { + diarioService.eliminar(id, usuario); + return "redirect:/diario"; + } +} diff --git a/src/main/java/es/tatvil/oracion/diario/DiarioRepository.java b/src/main/java/es/tatvil/oracion/diario/DiarioRepository.java new file mode 100644 index 0000000..b81b552 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/diario/DiarioRepository.java @@ -0,0 +1,12 @@ +package es.tatvil.oracion.diario; + +import es.tatvil.oracion.usuario.Usuario; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface DiarioRepository extends JpaRepository { + List findByUsuarioOrderByFechaDesc(Usuario usuario); + Optional findByIdAndUsuario(Long id, Usuario usuario); +} diff --git a/src/main/java/es/tatvil/oracion/diario/DiarioService.java b/src/main/java/es/tatvil/oracion/diario/DiarioService.java new file mode 100644 index 0000000..016eae0 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/diario/DiarioService.java @@ -0,0 +1,35 @@ +package es.tatvil.oracion.diario; + +import es.tatvil.oracion.usuario.Usuario; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DiarioService { + + private final DiarioRepository diarioRepository; + + public List listarPorUsuario(Usuario usuario) { + return diarioRepository.findByUsuarioOrderByFechaDesc(usuario); + } + + public Diario buscarPorIdYUsuario(Long id, Usuario usuario) { + return diarioRepository.findByIdAndUsuario(id, usuario) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + } + + public Diario guardar(Diario diario, Usuario usuario) { + diario.setUsuario(usuario); + return diarioRepository.save(diario); + } + + public void eliminar(Long id, Usuario usuario) { + Diario diario = buscarPorIdYUsuario(id, usuario); + diarioRepository.delete(diario); + } +} diff --git a/src/main/java/es/tatvil/oracion/difuntos/Difunto.java b/src/main/java/es/tatvil/oracion/difuntos/Difunto.java new file mode 100644 index 0000000..fba6d18 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/difuntos/Difunto.java @@ -0,0 +1,33 @@ +package es.tatvil.oracion.difuntos; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Table(name = "difuntos") +@Data +@NoArgsConstructor +public class Difunto { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String nombre; + + private LocalDate fechaFallecimiento; + + private String relacion; + + @Column(columnDefinition = "TEXT") + private String notas; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "usuario_id", nullable = false) + private Usuario usuario; +} diff --git a/src/main/java/es/tatvil/oracion/difuntos/DifuntoController.java b/src/main/java/es/tatvil/oracion/difuntos/DifuntoController.java new file mode 100644 index 0000000..9c3f6ce --- /dev/null +++ b/src/main/java/es/tatvil/oracion/difuntos/DifuntoController.java @@ -0,0 +1,46 @@ +package es.tatvil.oracion.difuntos; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +@Controller +@RequestMapping("/difuntos") +@RequiredArgsConstructor +public class DifuntoController { + + private final DifuntoService difuntoService; + + @GetMapping + public String lista(Model model, @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("difuntos", difuntoService.listarPorUsuario(usuario)); + return "difuntos/lista"; + } + + @GetMapping("/nuevo") + public String nuevoForm(Model model) { + model.addAttribute("difunto", new Difunto()); + return "difuntos/nuevo"; + } + + @PostMapping("/nuevo") + public String guardar(@Valid @ModelAttribute("difunto") Difunto difunto, + BindingResult result, + @AuthenticationPrincipal Usuario usuario) { + if (result.hasErrors()) return "difuntos/nuevo"; + difuntoService.guardar(difunto, usuario); + return "redirect:/difuntos"; + } + + @PostMapping("/{id}/eliminar") + public String eliminar(@PathVariable Long id, + @AuthenticationPrincipal Usuario usuario) { + difuntoService.eliminar(id, usuario); + return "redirect:/difuntos"; + } +} diff --git a/src/main/java/es/tatvil/oracion/difuntos/DifuntoRepository.java b/src/main/java/es/tatvil/oracion/difuntos/DifuntoRepository.java new file mode 100644 index 0000000..cb0c6e6 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/difuntos/DifuntoRepository.java @@ -0,0 +1,12 @@ +package es.tatvil.oracion.difuntos; + +import es.tatvil.oracion.usuario.Usuario; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface DifuntoRepository extends JpaRepository { + List findByUsuarioOrderByNombreAsc(Usuario usuario); + Optional findByIdAndUsuario(Long id, Usuario usuario); +} diff --git a/src/main/java/es/tatvil/oracion/difuntos/DifuntoService.java b/src/main/java/es/tatvil/oracion/difuntos/DifuntoService.java new file mode 100644 index 0000000..1e24d4d --- /dev/null +++ b/src/main/java/es/tatvil/oracion/difuntos/DifuntoService.java @@ -0,0 +1,35 @@ +package es.tatvil.oracion.difuntos; + +import es.tatvil.oracion.usuario.Usuario; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DifuntoService { + + private final DifuntoRepository difuntoRepository; + + public List listarPorUsuario(Usuario usuario) { + return difuntoRepository.findByUsuarioOrderByNombreAsc(usuario); + } + + public Difunto buscarPorIdYUsuario(Long id, Usuario usuario) { + return difuntoRepository.findByIdAndUsuario(id, usuario) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + } + + public Difunto guardar(Difunto difunto, Usuario usuario) { + difunto.setUsuario(usuario); + return difuntoRepository.save(difunto); + } + + public void eliminar(Long id, Usuario usuario) { + Difunto difunto = buscarPorIdYUsuario(id, usuario); + difuntoRepository.delete(difunto); + } +} diff --git a/src/main/java/es/tatvil/oracion/evangelio/EvangelioService.java b/src/main/java/es/tatvil/oracion/evangelio/EvangelioService.java new file mode 100644 index 0000000..a8d3610 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/evangelio/EvangelioService.java @@ -0,0 +1,32 @@ +package es.tatvil.oracion.evangelio; + +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.Locale; + +/** + * Servicio para el Evangelio del día. + * Actualmente muestra un mensaje de orientación. Para integrar con una API real, + * puedes usar, por ejemplo, https://evangelio.app o el feed RSS de ACIPRENSA. + */ +@Service +public class EvangelioService { + + public EvangelioDto getEvangelioDelDia() { + LocalDate hoy = LocalDate.now(); + String diaSemana = hoy.getDayOfWeek().getDisplayName(TextStyle.FULL, new Locale("es", "ES")); + String fecha = hoy.format(DateTimeFormatter.ofPattern("d 'de' MMMM 'de' yyyy", new Locale("es", "ES"))); + + return new EvangelioDto( + diaSemana.substring(0, 1).toUpperCase() + diaSemana.substring(1) + ", " + fecha, + "El Evangelio del día está disponible en:", + "https://www.ewtn.com/es/catolico/oraciones/evangelio-del-dia", + "Puedes consultar el Evangelio en EWTN, Vatican News o tu misal digital." + ); + } + + public record EvangelioDto(String titulo, String texto, String enlace, String nota) {} +} diff --git a/src/main/java/es/tatvil/oracion/oracion/Oracion.java b/src/main/java/es/tatvil/oracion/oracion/Oracion.java new file mode 100644 index 0000000..0434ee9 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/Oracion.java @@ -0,0 +1,44 @@ +package es.tatvil.oracion.oracion; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Table(name = "oraciones") +@Data +@NoArgsConstructor +public class Oracion { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String titulo; + + @Column(columnDefinition = "TEXT") + private String descripcion; + + @Column(nullable = false) + private LocalDate fechaCreacion; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private TipoOracion tipo; + + private boolean activa = true; + private boolean respondida = false; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "usuario_id", nullable = false) + private Usuario usuario; + + @PrePersist + public void prePersist() { + if (fechaCreacion == null) fechaCreacion = LocalDate.now(); + } +} diff --git a/src/main/java/es/tatvil/oracion/oracion/OracionController.java b/src/main/java/es/tatvil/oracion/oracion/OracionController.java new file mode 100644 index 0000000..5fc1bee --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/OracionController.java @@ -0,0 +1,58 @@ +package es.tatvil.oracion.oracion; + +import es.tatvil.oracion.usuario.Usuario; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +@Controller +@RequestMapping("/oraciones") +@RequiredArgsConstructor +public class OracionController { + + private final OracionService oracionService; + + @GetMapping + public String lista(Model model, @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("misOraciones", oracionService.listarPorUsuario(usuario)); + model.addAttribute("comunitarias", oracionService.listarComunitarias()); + return "oraciones/lista"; + } + + @GetMapping("/nueva") + public String nuevaForm(Model model) { + model.addAttribute("oracion", new Oracion()); + model.addAttribute("tipos", TipoOracion.values()); + return "oraciones/nueva"; + } + + @PostMapping("/nueva") + public String guardar(@Valid @ModelAttribute("oracion") Oracion oracion, + BindingResult result, Model model, + @AuthenticationPrincipal Usuario usuario) { + if (result.hasErrors()) { + model.addAttribute("tipos", TipoOracion.values()); + return "oraciones/nueva"; + } + oracionService.guardar(oracion, usuario); + return "redirect:/oraciones"; + } + + @PostMapping("/{id}/respondida") + public String marcarRespondida(@PathVariable Long id, + @AuthenticationPrincipal Usuario usuario) { + oracionService.marcarRespondida(id, usuario); + return "redirect:/oraciones"; + } + + @PostMapping("/{id}/eliminar") + public String eliminar(@PathVariable Long id, + @AuthenticationPrincipal Usuario usuario) { + oracionService.eliminar(id, usuario); + return "redirect:/oraciones"; + } +} diff --git a/src/main/java/es/tatvil/oracion/oracion/OracionRepository.java b/src/main/java/es/tatvil/oracion/oracion/OracionRepository.java new file mode 100644 index 0000000..ccf1e72 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/OracionRepository.java @@ -0,0 +1,13 @@ +package es.tatvil.oracion.oracion; + +import es.tatvil.oracion.usuario.Usuario; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface OracionRepository extends JpaRepository { + List findByUsuarioOrderByFechaCreacionDesc(Usuario usuario); + List findByTipoOrderByFechaCreacionDesc(TipoOracion tipo); + Optional findByIdAndUsuario(Long id, Usuario usuario); +} diff --git a/src/main/java/es/tatvil/oracion/oracion/OracionService.java b/src/main/java/es/tatvil/oracion/oracion/OracionService.java new file mode 100644 index 0000000..1ee81c5 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/OracionService.java @@ -0,0 +1,46 @@ +package es.tatvil.oracion.oracion; + +import es.tatvil.oracion.usuario.Usuario; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class OracionService { + + private final OracionRepository oracionRepository; + + public List listarPorUsuario(Usuario usuario) { + return oracionRepository.findByUsuarioOrderByFechaCreacionDesc(usuario); + } + + public List listarComunitarias() { + return oracionRepository.findByTipoOrderByFechaCreacionDesc(TipoOracion.COMUNITARIA); + } + + public Oracion buscarPorIdYUsuario(Long id, Usuario usuario) { + return oracionRepository.findByIdAndUsuario(id, usuario) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + } + + public Oracion guardar(Oracion oracion, Usuario usuario) { + oracion.setUsuario(usuario); + return oracionRepository.save(oracion); + } + + public void marcarRespondida(Long id, Usuario usuario) { + Oracion oracion = buscarPorIdYUsuario(id, usuario); + oracion.setRespondida(true); + oracion.setActiva(false); + oracionRepository.save(oracion); + } + + public void eliminar(Long id, Usuario usuario) { + Oracion oracion = buscarPorIdYUsuario(id, usuario); + oracionRepository.delete(oracion); + } +} diff --git a/src/main/java/es/tatvil/oracion/oracion/TipoOracion.java b/src/main/java/es/tatvil/oracion/oracion/TipoOracion.java new file mode 100644 index 0000000..fb5d02d --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/TipoOracion.java @@ -0,0 +1,5 @@ +package es.tatvil.oracion.oracion; + +public enum TipoOracion { + PRIVADA, COMUNITARIA +} diff --git a/src/main/java/es/tatvil/oracion/oracion/oracion.md b/src/main/java/es/tatvil/oracion/oracion/oracion.md new file mode 100644 index 0000000..be82e9f --- /dev/null +++ b/src/main/java/es/tatvil/oracion/oracion/oracion.md @@ -0,0 +1 @@ +Para peticiones privadas/comunitarias \ No newline at end of file diff --git a/src/main/java/es/tatvil/oracion/salmo/SalmoService.java b/src/main/java/es/tatvil/oracion/salmo/SalmoService.java new file mode 100644 index 0000000..03005a2 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/salmo/SalmoService.java @@ -0,0 +1,42 @@ +package es.tatvil.oracion.salmo; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import java.io.IOException; +import java.util.List; + +@Service +public class SalmoService { + private static final List SALMOS; + static { + ObjectMapper mapper = new ObjectMapper(); + List salmosTmp = List.of(); + try { + var resource = new ClassPathResource("data/salmos.json"); + if (resource.exists()) { + salmosTmp = mapper.readValue(resource.getInputStream(), new TypeReference>(){}); + } + } catch (IOException e) { + // fallback: lista vacía + } + SALMOS = salmosTmp; + } + + public Salmo getSalmoDelDia() { + if (SALMOS.isEmpty()) return new Salmo(0, "No hay salmo disponible"); + int index = SALMOS.size() / 2; + return SALMOS.get(index); + } + + public static class Salmo { + public int numero; + public String texto; + public Salmo() {} + public Salmo(int numero, String texto) { + this.numero = numero; + this.texto = texto; + } + } +} diff --git a/src/main/java/es/tatvil/oracion/santo/SantoService.java b/src/main/java/es/tatvil/oracion/santo/SantoService.java new file mode 100644 index 0000000..cdc8439 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/santo/SantoService.java @@ -0,0 +1,49 @@ +package es.tatvil.oracion.santo; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +@Service +public class SantoService { + private static final Map SANTOS = new HashMap<>(); + static { + ObjectMapper mapper = new ObjectMapper(); + try { + var resource = new ClassPathResource("data/santos.json"); + if (resource.exists()) { + Map map = mapper.readValue(resource.getInputStream(), new TypeReference>(){}); + SANTOS.putAll(map); + } + } catch (IOException e) { + // fallback: no carga nada + } + } + + public SantoInfo getSantoDelDia() { + String clave = LocalDate.now().format(DateTimeFormatter.ofPattern("MM-dd")); + return SANTOS.getOrDefault(clave, new SantoInfo("Santo/a del día", "")); + } + + public SantoInfo getSantoDelDia(LocalDate fecha) { + String clave = fecha.format(DateTimeFormatter.ofPattern("MM-dd")); + return SANTOS.getOrDefault(clave, new SantoInfo("Santo/a del día", "")); + } + + public static class SantoInfo { + public String nombre; + public String descripcion; + public SantoInfo() {} + public SantoInfo(String nombre, String descripcion) { + this.nombre = nombre; + this.descripcion = descripcion; + } + } +} diff --git a/src/main/java/es/tatvil/oracion/usuario/Usuario.java b/src/main/java/es/tatvil/oracion/usuario/Usuario.java new file mode 100644 index 0000000..d39125b --- /dev/null +++ b/src/main/java/es/tatvil/oracion/usuario/Usuario.java @@ -0,0 +1,52 @@ +package es.tatvil.oracion.usuario; + +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; + +@Entity +@Table(name = "usuarios") +@Data +@NoArgsConstructor +public class Usuario implements UserDetails { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(unique = true, nullable = false) + private String email; + + @Column(nullable = false) + private String nombre; + + @Column(nullable = false) + private String password; + + private boolean enabled = true; + + @Override + public Collection getAuthorities() { + return List.of(new SimpleGrantedAuthority("ROLE_USER")); + } + + @Override + public String getUsername() { + return email; + } + + @Override + public boolean isAccountNonExpired() { return true; } + + @Override + public boolean isAccountNonLocked() { return true; } + + @Override + public boolean isCredentialsNonExpired() { return true; } +} diff --git a/src/main/java/es/tatvil/oracion/usuario/UsuarioRepository.java b/src/main/java/es/tatvil/oracion/usuario/UsuarioRepository.java new file mode 100644 index 0000000..eca3d50 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/usuario/UsuarioRepository.java @@ -0,0 +1,10 @@ +package es.tatvil.oracion.usuario; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UsuarioRepository extends JpaRepository { + Optional findByEmail(String email); + boolean existsByEmail(String email); +} diff --git a/src/main/java/es/tatvil/oracion/usuario/UsuarioService.java b/src/main/java/es/tatvil/oracion/usuario/UsuarioService.java new file mode 100644 index 0000000..dff0cf9 --- /dev/null +++ b/src/main/java/es/tatvil/oracion/usuario/UsuarioService.java @@ -0,0 +1,31 @@ +package es.tatvil.oracion.usuario; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UsuarioService implements UserDetailsService { + + private final UsuarioRepository usuarioRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + return usuarioRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado: " + email)); + } + + public boolean existeEmail(String email) { + return usuarioRepository.existsByEmail(email); + } + + public void registrar(Usuario usuario) { + usuario.setPassword(passwordEncoder.encode(usuario.getPassword())); + usuarioRepository.save(usuario); + } +} diff --git a/src/main/java/es/tatvil/oracion/web/HomeController.java b/src/main/java/es/tatvil/oracion/web/HomeController.java new file mode 100644 index 0000000..f1aa46f --- /dev/null +++ b/src/main/java/es/tatvil/oracion/web/HomeController.java @@ -0,0 +1,72 @@ +package es.tatvil.oracion.web; + +import es.tatvil.oracion.difuntos.DifuntoService; +import es.tatvil.oracion.evangelio.EvangelioService; +import es.tatvil.oracion.oracion.OracionService; +import es.tatvil.oracion.oracion.TipoOracion; +import es.tatvil.oracion.santo.SantoService; +import es.tatvil.oracion.usuario.Usuario; +import es.tatvil.oracion.salmo.SalmoService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import java.time.LocalDate; +import java.time.format.TextStyle; +import java.util.Locale; + +@Controller +@RequiredArgsConstructor + +public class HomeController { + private final SantoService santoService; + private final EvangelioService evangelioService; + private final OracionService oracionService; + private final DifuntoService difuntoService; + private final SalmoService salmoService; + + + @GetMapping("/") + public String home(Model model, @AuthenticationPrincipal Usuario usuario) { + // Fecha actual en formato largo + LocalDate hoy = LocalDate.now(); + String fechaHoy = hoy.getDayOfWeek().getDisplayName(TextStyle.FULL, new Locale("es")) + + ", " + hoy.getDayOfMonth() + " de " + hoy.getMonth().getDisplayName(TextStyle.FULL, new Locale("es")) + + " de " + hoy.getYear(); + + // Ciclo litúrgico (simplificado: A/B/C según año) + String[] ciclos = {"A", "B", "C"}; + String nombreCiclo = ciclos[(hoy.getYear() % 3)]; + String cicloParImpar = (hoy.getYear() % 2 == 0) ? "Año Par" : "Año Impar"; + + // Color litúrgico (simplificado: verde por defecto) + String colorLiturgico = "#2d5a27"; + String nombreLiturgico = "Tiempo Ordinario"; + + + // Santo del día (nombre y descripción desde JSON) + SantoService.SantoInfo santoInfo = santoService.getSantoDelDia(); + + model.addAttribute("fechaHoy", fechaHoy); + model.addAttribute("nombreCiclo", nombreCiclo); + model.addAttribute("cicloParImpar", cicloParImpar); + model.addAttribute("colorLiturgico", colorLiturgico); + model.addAttribute("nombreLiturgico", nombreLiturgico); + model.addAttribute("santo", santoInfo); + model.addAttribute("salmo", salmoService.getSalmoDelDia()); + + return "home"; + } + // Ya no se necesita DTO, se usa SantoInfo + + @GetMapping("/inicio") + public String inicio(Model model, @AuthenticationPrincipal Usuario usuario) { + model.addAttribute("santo", santoService.getSantoDelDia()); + model.addAttribute("evangelio", evangelioService.getEvangelioDelDia()); + model.addAttribute("peticionesComunitarias", + oracionService.listarComunitarias().stream().filter(o -> o.isActiva()).limit(5).toList()); + model.addAttribute("misDifuntos", difuntoService.listarPorUsuario(usuario)); + return "inicio"; + } +} diff --git a/src/main/java/es/tatvil/oracion/web/RegistroController.java b/src/main/java/es/tatvil/oracion/web/RegistroController.java new file mode 100644 index 0000000..237976f --- /dev/null +++ b/src/main/java/es/tatvil/oracion/web/RegistroController.java @@ -0,0 +1,41 @@ +package es.tatvil.oracion.web; + +import es.tatvil.oracion.usuario.Usuario; +import es.tatvil.oracion.usuario.UsuarioService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/registro") +@RequiredArgsConstructor +public class RegistroController { + + private final UsuarioService usuarioService; + + @GetMapping + public String mostrarFormulario(Model model) { + model.addAttribute("usuario", new Usuario()); + return "registro"; + } + + @PostMapping + public String registrar(@Valid @ModelAttribute("usuario") Usuario usuario, + BindingResult result, Model model) { + if (result.hasErrors()) { + return "registro"; + } + if (usuarioService.existeEmail(usuario.getEmail())) { + model.addAttribute("errorEmail", "Ya existe una cuenta con ese email."); + return "registro"; + } + usuarioService.registrar(usuario); + return "redirect:/login?registrado"; + } +} diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..1031b04 --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,14 @@ +# Perfil de desarrollo con H2 (base de datos en memoria) +# Usar con: gradlew bootRun --args='--spring.profiles.active=dev' + +spring.datasource.url=jdbc:h2:mem:oracion_dev;DB_CLOSE_DELAY=-1 +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect + +# Consola H2 (http://localhost:8080/h2-console) +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..8e0b1d3 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,19 @@ +spring.application.name=oracion + +# Base de datos MySQL +spring.datasource.url=jdbc:mysql://localhost:3306/oracion_db?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=Europe/Madrid&allowPublicKeyRetrieval=true +spring.datasource.username=root +spring.datasource.password= +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +# JPA / Hibernate +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=false +spring.jpa.properties.hibernate.format_sql=true + +# Thymeleaf +spring.thymeleaf.cache=false +spring.thymeleaf.encoding=UTF-8 + +# Servidor +server.port=8080 diff --git a/src/main/resources/data/calendario-liturgico.json b/src/main/resources/data/calendario-liturgico.json new file mode 100644 index 0000000..d733f35 --- /dev/null +++ b/src/main/resources/data/calendario-liturgico.json @@ -0,0 +1,356 @@ +[ + { "fecha": "2026-01-01", "color": "blanco", "tiempo": "Navidad (Sta. María, Madre de Dios)" }, + { "fecha": "2026-01-04", "color": "blanco", "tiempo": "Navidad (II Domingo después de Navidad)" }, + { "fecha": "2026-01-06", "color": "blanco", "tiempo": "Navidad (Epifanía del Señor)" }, + { "fecha": "2026-01-11", "color": "blanco", "tiempo": "Navidad (Bautismo del Señor)" }, + { "fecha": "2026-01-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-25", "color": "blanco", "tiempo": "Tiempo Ordinario (Conversión de San Pablo)" }, + { "fecha": "2026-01-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-01-31", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-02", "color": "blanco", "tiempo": "Tiempo Ordinario (Presentación del Señor)" }, + { "fecha": "2026-02-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-12", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-02-15", "color": "verde", "tiempo": "Domingo de Carnaval" }, + { "fecha": "2026-02-16", "color": "verde", "tiempo": "Carnaval (Lunes de Carnaval)" }, + { "fecha": "2026-02-17", "color": "verde", "tiempo": "Carnaval (Martes de Carnaval)" }, + { "fecha": "2026-02-18", "color": "morado", "tiempo": "Cuaresma (Miércoles de Ceniza)" }, + { "fecha": "2026-02-19", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-20", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-21", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-22", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-23", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-24", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-25", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-26", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-27", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-02-28", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-01", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-02", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-03", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-04", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-05", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-06", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-07", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-08", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-09", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-10", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-11", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-12", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-13", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-14", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-15", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-16", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-17", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-18", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-19", "color": "blanco", "tiempo": "Cuaresma (San José)" }, + { "fecha": "2026-03-20", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-21", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-22", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-23", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-24", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-25", "color": "violeta", "tiempo": "Cuaresma (Anunciación del Señor)" }, + { "fecha": "2026-03-26", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-27", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-28", "color": "morado", "tiempo": "Cuaresma" }, + { "fecha": "2026-03-29", "color": "rojo", "tiempo": "Semana Santa (Domingo de Ramos)" }, + { "fecha": "2026-03-30", "color": "morado", "tiempo": "Lunes de Semana Santa" }, + { "fecha": "2026-03-31", "color": "morado", "tiempo": "Martes de Semana Santa" }, + { "fecha": "2026-04-01", "color": "morado", "tiempo": "Semana Santa" }, + { "fecha": "2026-04-02", "color": "blanco", "tiempo": "Semana Santa (Jueves Santo)" }, + { "fecha": "2026-04-03", "color": "rojo", "tiempo": "Semana Santa (Viernes Santo)" }, + { "fecha": "2026-04-04", "color": "morado/negro", "tiempo": "Semana Santa" }, + { "fecha": "2026-04-05", "color": "blanco", "tiempo": "Semana Santa (Domingo de Resurrección)" }, + { "fecha": "2026-04-06", "color": "morado", "tiempo": "Lunes de Pascua" }, + { "fecha": "2026-04-07", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-08", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-09", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-10", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-11", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-12", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-13", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-14", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-15", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-16", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-17", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-18", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-19", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-20", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-21", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-22", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-23", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-24", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-25", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-26", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-27", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-28", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-29", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-04-30", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-01", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-02", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-03", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-04", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-05", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-06", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-07", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-08", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-09", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-10", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-11", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-12", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-13", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-14", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-15", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-16", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-17", "color": "blanco", "tiempo": "Tiempo Pascual (Ascensión del Señor)" }, + { "fecha": "2026-05-18", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-19", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-20", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-21", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-22", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-23", "color": "morado", "tiempo": "Tiempo Pascual" }, + { "fecha": "2026-05-24", "color": "rojo", "tiempo": "Tiempo Pascual (Pentecostés)" }, + { "fecha": "2026-05-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-05-31", "color": "blanco", "tiempo": "Tiempo Ordinario (Santísima Trinidad)" }, + { "fecha": "2026-06-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-02", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-07", "color": "blanco", "tiempo": "Tiempo Ordinario (Corpus Christi)" }, + { "fecha": "2026-06-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-12", "color": "blanco", "tiempo": "Tiempo Ordinario (Sagrado Corazón de Jesús)" }, + { "fecha": "2026-06-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-15", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-24", "color": "blanco", "tiempo": "Tiempo Ordinario (Natividad de San Juan Bautista)" }, + { "fecha": "2026-06-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-06-29", "color": "rojo", "tiempo": "Tiempo Ordinario (San Pedro y San Pablo)" }, + { "fecha": "2026-06-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-02", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-12", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-15", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-25", "color": "blanco", "tiempo": "Tiempo Ordinario (Santiago Apóstol)" }, + { "fecha": "2026-07-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-07-31", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-02", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-12", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-15", "color": "blanco", "tiempo": "Tiempo Ordinario (Asunción de la Virgen)" }, + { "fecha": "2026-08-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-08-31", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-02", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-12", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-15", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-09-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-01", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-02", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-12", "color": "blanco", "tiempo": "Nuestra Señora del Pilar" }, + { "fecha": "2026-10-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-15", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-22", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-29", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-30", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-10-31", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-01", "color": "blanco", "tiempo": "Tiempo Ordinario (Todos los Santos)" }, + { "fecha": "2026-11-02", "color": "morado/negro", "tiempo": "Tiempo Ordinario (Fieles Difuntos)" }, + { "fecha": "2026-11-03", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-04", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-05", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-06", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-07", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-08", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-09", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-10", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-11", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-12", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-13", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-14", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-15", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-16", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-17", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-18", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-19", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-20", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-21", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-22", "color": "blanco", "tiempo": "Tiempo Ordinario (Cristo Rey)" }, + { "fecha": "2026-11-23", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-24", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-25", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-26", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-27", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-28", "color": "verde", "tiempo": "Tiempo Ordinario" }, + { "fecha": "2026-11-29", "color": "morado", "tiempo": "Adviento (I Domingo de Adviento)" }, + { "fecha": "2026-11-30", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-01", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-02", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-03", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-04", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-05", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-06", "color": "morado", "tiempo": "Adviento (II Domingo de Adviento)" }, + { "fecha": "2026-12-07", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-08", "color": "azul/blanco", "tiempo": "Adviento (Inmaculada Concepción)" }, + { "fecha": "2026-12-09", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-10", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-11", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-12", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-13", "color": "morado", "tiempo": "Adviento (III Domingo de Adviento)" }, + { "fecha": "2026-12-14", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-15", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-16", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-17", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-18", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-19", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-20", "color": "morado", "tiempo": "Adviento (IV Domingo de Adviento)" }, + { "fecha": "2026-12-21", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-22", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-23", "color": "morado", "tiempo": "Adviento" }, + { "fecha": "2026-12-24", "color": "morado/blanco", "tiempo": "Adviento (Nochebuena)" }, + { "fecha": "2026-12-25", "color": "blanco", "tiempo": "Navidad (Natividad del Señor)" }, + { "fecha": "2026-12-26", "color": "blanco", "tiempo": "Navidad (San Esteban)" }, + { "fecha": "2026-12-27", "color": "blanco", "tiempo": "Navidad (San Juan Evangelista)" }, + { "fecha": "2026-12-28", "color": "blanco", "tiempo": "Navidad (Inocentes)" }, + { "fecha": "2026-12-29", "color": "blanco", "tiempo": "Navidad" }, + { "fecha": "2026-12-30", "color": "blanco", "tiempo": "Navidad" }, + { "fecha": "2026-12-31", "color": "blanco", "tiempo": "Navidad" } +] + \ No newline at end of file diff --git a/src/main/resources/data/proverbios.json b/src/main/resources/data/proverbios.json new file mode 100644 index 0000000..76685b3 --- /dev/null +++ b/src/main/resources/data/proverbios.json @@ -0,0 +1,102 @@ +[ + { "numero": 1, "texto": "El temor del Señor es el principio de la sabiduría; los necios desprecian la sabiduría y la instrucción." }, + { "numero": 2, "texto": "El Señor da la sabiduría; de su boca vienen el conocimiento y la inteligencia." }, + { "numero": 3, "texto": "Confía en el Señor con todo tu corazón, y no te apoyes en tu propia prudencia. Él enderezará tus sendas." }, + { "numero": 4, "texto": "Guarda, hijo mío, el mandamiento de tu padre, y no abandones la enseñanza de tu madre." }, + { "numero": 5, "texto": "Bebe el agua de tu propia cisterna. Bendita sea tu fuente, y alégrate con la mujer de tu juventud." }, + { "numero": 6, "texto": "Ve a la hormiga, oh perezoso, mira sus caminos, y sé sabio. Ella sin tener capitán trabaja." }, + { "numero": 7, "texto": "La sabiduría edificó su casa. Venid, comed mi pan, y bebed del vino que yo he mezclado." }, + { "numero": 8, "texto": "El que halla una esposa halla el bien, y alcanza la benevolencia del Señor." }, + { "numero": 9, "texto": "Orgullo, arrogancia, mal camino y boca perversa aborrezco. Conmigo están el consejo y el buen juicio." }, + { "numero": 10, "texto": "El recuerdo del justo es bendito, pero el nombre de los impíos se pudrirá." }, + { "numero": 11, "texto": "El que confía en sus riquezas caerá; pero los justos reverdecerán como ramas." }, + { "numero": 12, "texto": "El que trabaja su tierra se saciará de pan; mas el que sigue a los vagabundos es falto de entendimiento." }, + { "numero": 13, "texto": "El que guarda su boca guarda su alma; mas el que abre mucho sus labios tendrá calamidad." }, + { "numero": 14, "texto": "En el corazón del entendido reposa la sabiduría; pero lo que está en el interior del necio se da a conocer." }, + { "numero": 15, "texto": "La respuesta suave aplaca la ira, pero la palabra áspera hace subir el furor." }, + { "numero": 16, "texto": "El hombre propone, y Dios dispone. Encomienda al Señor tus obras, y tus pensamientos serán afirmados." }, + { "numero": 17, "texto": "En todo tiempo ama el amigo, y es como un hermano en tiempo de angustia." }, + { "numero": 18, "texto": "El nombre del Señor es torre fuerte; a él corre el justo, y está a salvo." }, + { "numero": 19, "texto": "El que obtiene sabiduría ama su propia alma; el que guarda la inteligencia hallará el bien." }, + { "numero": 20, "texto": "El vino es escarnecedor, la sidra alborotadora; y cualquiera que por ellos yerra no es sabio." }, + { "numero": 21, "texto": "El corazón del hombre piensa su camino; mas el Señor endereza sus pasos." }, + { "numero": 22, "texto": "Instruye al niño en su camino, y aun cuando fuere viejo no se apartará de él." }, + { "numero": 23, "texto": "No te afanes por hacerte rico; sé prudente, y desiste. ¿Has de poner tus ojos en las riquezas que se van?" }, + { "numero": 24, "texto": "Si cayeres siete veces, te levantarás; pero los impíos caerán en el mal." }, + { "numero": 25, "texto": "Como ciudad derribada y sin muro es el hombre cuyo espíritu no tiene rienda." }, + { "numero": 26, "texto": "Como perro que vuelve a su vómito, así es el necio que repite su necedad." }, + { "numero": 27, "texto": "No te jactes del día de mañana, porque no sabes qué dará de sí el día. Alábete el extraño, y no tu propia boca." }, + { "numero": 28, "texto": "El que encubre sus pecados no prosperará; mas el que los confiesa y se aparta alcanzará misericordia." }, + { "numero": 29, "texto": "Cuando los justos se alegran, hay gran gloria; pero cuando los impíos suben, el pueblo gime." }, + { "numero": 30, "texto": "Dos cosas te he demandado; no me las niegues: Aleja de mí la vanidad y la mentira; dame solo lo necesario." }, + { "numero": 31, "texto": "Mujer virtuosa, ¿quién la hallará? Su precio sobrepasa largamente al de las piedras preciosas." }, + { "numero": 32, "texto": "La sabiduría clama en las calles, da su voz en las plazas. ¿Hasta cuándo amaréis la simpleza?" }, + { "numero": 33, "texto": "El corazón alegre es buena medicina; mas el espíritu triste seca los huesos." }, + { "numero": 34, "texto": "Mejor es un bocado seco, y en paz, que casa de contiendas llena de provisiones." }, + { "numero": 35, "texto": "El hierro con el hierro se aguza; y así el hombre aguza el rostro de su amigo." }, + { "numero": 36, "texto": "Más confiable es el que reprende abiertamente que el que lisonjea en secreto." }, + { "numero": 37, "texto": "Como el águila que se remonta, tal es el hombre que está seguro en el temor del Señor." }, + { "numero": 38, "texto": "Donde no hay visión, el pueblo se extravía; pero dichoso el que guarda la ley." }, + { "numero": 39, "texto": "La vara y la corrección dan sabiduría; mas el muchacho consentido avergonzará a su madre." }, + { "numero": 40, "texto": "El pobre y el rico se encuentran; a ambos los hizo el Señor." }, + { "numero": 41, "texto": "No hagas al mal a nadie que en ti confía; no respondas mal al que contigo bien ha hecho." }, + { "numero": 42, "texto": "El hombre sabio es fuerte, y el hombre de conocimiento aumenta el poder." }, + { "numero": 43, "texto": "La sabiduría es mejor que las armas de guerra; pero un solo pecador destruye mucho bien." }, + { "numero": 44, "texto": "El que guarda la ley es hijo prudente; mas el que es compañero de glotones avergüenza a su padre." }, + { "numero": 45, "texto": "Honra al Señor con tus bienes, y con las primicias de todos tus frutos. Así tus graneros estarán llenos." }, + { "numero": 46, "texto": "Bienaventurado el hombre que halla la sabiduría; porque su ganancia es mejor que la de la plata." }, + { "numero": 47, "texto": "No envidies al hombre violento, ni escojas ninguno de sus caminos. Porque el Señor abomina al perverso." }, + { "numero": 48, "texto": "El testigo fiel no mentirá; mas el testigo falso hablará mentiras." }, + { "numero": 49, "texto": "La esperanza que se demora es tormento del corazón; pero árbol de vida es el deseo cumplido." }, + { "numero": 50, "texto": "El camino del necio es derecho en su opinión; mas el que obedece el consejo es sabio." }, + { "numero": 51, "texto": "El orgullo del hombre le acarrea humillación; pero al humilde de espíritu sustenta la honra." }, + { "numero": 52, "texto": "Los que buscan al Señor no carecerán de ningún bien. El temor del Señor prolonga los días." }, + { "numero": 53, "texto": "La justicia engrandece a la nación; mas el pecado es mengua de los pueblos." }, + { "numero": 54, "texto": "En la lengua hay poder de vida y de muerte; los que la aman comerán de sus frutos." }, + { "numero": 55, "texto": "El que es tardo para la ira es grande de entendimiento; mas el que es impaciente de espíritu enaltece la necedad." }, + { "numero": 56, "texto": "El camino del perezoso es como seto de espinos; mas la vereda de los rectos, como una calzada." }, + { "numero": 57, "texto": "El que da al pobre no tendrá pobreza; mas el que aparta sus ojos tendrá muchas maldiciones." }, + { "numero": 58, "texto": "No te alegres cuando caiga tu enemigo, y no se regocije tu corazón cuando tropiece." }, + { "numero": 59, "texto": "Como aguas profundas es el consejo en el corazón del hombre; mas el hombre entendido lo alcanzará." }, + { "numero": 60, "texto": "Muchos hombres proclaman cada uno su propia bondad, pero el hombre de verdad, ¿quién lo hallará?" }, + { "numero": 61, "texto": "El camino del justo es como la luz de la aurora, que va en aumento hasta que el día es perfecto." }, + { "numero": 62, "texto": "Sobre toda cosa guardada, guarda tu corazón; porque de él mana la vida." }, + { "numero": 63, "texto": "No dejes para mañana lo que puedes hacer hoy; los planes del diligente ciertamente son ventajosos." }, + { "numero": 64, "texto": "El rico y el pobre se encuentran; el Señor es el hacedor de todos ellos." }, + { "numero": 65, "texto": "Mejor es adquirir sabiduría que oro preciado; y adquirir inteligencia vale más que la plata." }, + { "numero": 66, "texto": "El que anda en integridad anda seguro; mas el que pervierte sus caminos será quebrantado." }, + { "numero": 67, "texto": "No te jactes de la sabiduría, ni de la valentía, ni de las riquezas; mas alábese en esto el que se hubiere de alabar: en entenderme y conocerme." }, + { "numero": 68, "texto": "Así como el agua refleja el rostro, el corazón del hombre refleja al hombre." }, + { "numero": 69, "texto": "El que reprende al hombre hallará después más gracia que el que lisonjea con la lengua." }, + { "numero": 70, "texto": "Teme al Señor, y apártate del mal; porque esto será medicina para tu cuerpo, y refrigerio para tus huesos." }, + { "numero": 71, "texto": "Dios es refugio del pobre, refugio en el tiempo de angustia. No olvides al menesteroso." }, + { "numero": 72, "texto": "Al necio, en su propia opinión, le parece bien todo lo que hace; mas el sabio escucha consejos." }, + { "numero": 73, "texto": "El vientre del impío no se saciará; mas el alma de los justos será saciada." }, + { "numero": 74, "texto": "Panal de miel son los dichos suaves; suavidad al alma y medicina para los huesos." }, + { "numero": 75, "texto": "El que perdona la ofensa cultiva el amor; el que insiste en la ofensa divide a los amigos." }, + { "numero": 76, "texto": "Mejor es un plato de legumbres donde hay amor, que buey engordado donde hay odio." }, + { "numero": 77, "texto": "Los pensamientos del diligente ciertamente tienden a la abundancia; mas todo el que se apresura alocadamente, de cierto va a la pobreza." }, + { "numero": 78, "texto": "El corazón del hombre traza su rumbo, pero sus pasos los dirige el Señor." }, + { "numero": 79, "texto": "La mentira aborrece a sus víctimas y la adulación hace daño. El testigo verdadero libra las almas." }, + { "numero": 80, "texto": "Sin leña se apaga el fuego, y donde no hay chismoso, cesa la contienda." }, + { "numero": 81, "texto": "Cada uno es recompensado conforme a su justicia; porque el Señor conoce el corazón." }, + { "numero": 82, "texto": "El que fuere soberbio será abatido; pero el de espíritu humilde obtendrá honra." }, + { "numero": 83, "texto": "El que labra su tierra tendrá abundancia de pan; mas el que sigue a los ociosos se llenará de pobreza." }, + { "numero": 84, "texto": "No hay sabiduría, ni inteligencia, ni consejo, contra el Señor." }, + { "numero": 85, "texto": "El que sigue la justicia y la misericordia hallará la vida, la justicia y la honra." }, + { "numero": 86, "texto": "No hagas nada por contienda o por vanagloria; estima a los demás como superiores a ti mismo." }, + { "numero": 87, "texto": "Lo que el impío teme, eso le vendrá; pero a los justos les será dado lo que desean." }, + { "numero": 88, "texto": "Una palabra dicha a su tiempo, ¡cuán buena es! Como manzanas de oro con figuras de plata." }, + { "numero": 89, "texto": "El hombre que no gobierna su espíritu es como ciudad derribada y sin muros." }, + { "numero": 90, "texto": "Dichoso el hombre que siempre teme al Señor; mas el que endurece su corazón caerá en el mal." }, + { "numero": 91, "texto": "Tres cosas me son ocultas; aun tampoco sé la cuarta: el rastro del águila en el aire, el rastro de la serpiente sobre la peña." }, + { "numero": 92, "texto": "No menosprecies a tu madre cuando fuere vieja. Compra la verdad, y no la vendas." }, + { "numero": 93, "texto": "El ojo que escarnece a su padre y menosprecia la instrucción de la madre, lo sacarán los cuervos del valle." }, + { "numero": 94, "texto": "El generoso prosperará; el que da agua, agua recibirá. Como el tú trates a los demás, así serás tratado." }, + { "numero": 95, "texto": "El hombre fiel tendrá muchas bendiciones; mas el que se apresura a enriquecerse no quedará sin castigo." }, + { "numero": 96, "texto": "El que tiene misericordia del pobre, a Dios presta; y él le devolverá su bien." }, + { "numero": 97, "texto": "La soberbia del hombre lo abate; pero al humilde de espíritu lo sustenta la honra." }, + { "numero": 98, "texto": "En todo trabajo hay fruto; mas las vanas palabras de los labios empobrecen." }, + { "numero": 99, "texto": "El corazón del hombre es profundo como el agua; mas el hombre entendido lo sondea." }, + { "numero": 100, "texto": "Mejor es el fin de un asunto que su principio; mejor es el ánimo paciente que el ánimo altivo." } +] diff --git a/src/main/resources/data/salmos.json b/src/main/resources/data/salmos.json new file mode 100644 index 0000000..76685b3 --- /dev/null +++ b/src/main/resources/data/salmos.json @@ -0,0 +1,102 @@ +[ + { "numero": 1, "texto": "El temor del Señor es el principio de la sabiduría; los necios desprecian la sabiduría y la instrucción." }, + { "numero": 2, "texto": "El Señor da la sabiduría; de su boca vienen el conocimiento y la inteligencia." }, + { "numero": 3, "texto": "Confía en el Señor con todo tu corazón, y no te apoyes en tu propia prudencia. Él enderezará tus sendas." }, + { "numero": 4, "texto": "Guarda, hijo mío, el mandamiento de tu padre, y no abandones la enseñanza de tu madre." }, + { "numero": 5, "texto": "Bebe el agua de tu propia cisterna. Bendita sea tu fuente, y alégrate con la mujer de tu juventud." }, + { "numero": 6, "texto": "Ve a la hormiga, oh perezoso, mira sus caminos, y sé sabio. Ella sin tener capitán trabaja." }, + { "numero": 7, "texto": "La sabiduría edificó su casa. Venid, comed mi pan, y bebed del vino que yo he mezclado." }, + { "numero": 8, "texto": "El que halla una esposa halla el bien, y alcanza la benevolencia del Señor." }, + { "numero": 9, "texto": "Orgullo, arrogancia, mal camino y boca perversa aborrezco. Conmigo están el consejo y el buen juicio." }, + { "numero": 10, "texto": "El recuerdo del justo es bendito, pero el nombre de los impíos se pudrirá." }, + { "numero": 11, "texto": "El que confía en sus riquezas caerá; pero los justos reverdecerán como ramas." }, + { "numero": 12, "texto": "El que trabaja su tierra se saciará de pan; mas el que sigue a los vagabundos es falto de entendimiento." }, + { "numero": 13, "texto": "El que guarda su boca guarda su alma; mas el que abre mucho sus labios tendrá calamidad." }, + { "numero": 14, "texto": "En el corazón del entendido reposa la sabiduría; pero lo que está en el interior del necio se da a conocer." }, + { "numero": 15, "texto": "La respuesta suave aplaca la ira, pero la palabra áspera hace subir el furor." }, + { "numero": 16, "texto": "El hombre propone, y Dios dispone. Encomienda al Señor tus obras, y tus pensamientos serán afirmados." }, + { "numero": 17, "texto": "En todo tiempo ama el amigo, y es como un hermano en tiempo de angustia." }, + { "numero": 18, "texto": "El nombre del Señor es torre fuerte; a él corre el justo, y está a salvo." }, + { "numero": 19, "texto": "El que obtiene sabiduría ama su propia alma; el que guarda la inteligencia hallará el bien." }, + { "numero": 20, "texto": "El vino es escarnecedor, la sidra alborotadora; y cualquiera que por ellos yerra no es sabio." }, + { "numero": 21, "texto": "El corazón del hombre piensa su camino; mas el Señor endereza sus pasos." }, + { "numero": 22, "texto": "Instruye al niño en su camino, y aun cuando fuere viejo no se apartará de él." }, + { "numero": 23, "texto": "No te afanes por hacerte rico; sé prudente, y desiste. ¿Has de poner tus ojos en las riquezas que se van?" }, + { "numero": 24, "texto": "Si cayeres siete veces, te levantarás; pero los impíos caerán en el mal." }, + { "numero": 25, "texto": "Como ciudad derribada y sin muro es el hombre cuyo espíritu no tiene rienda." }, + { "numero": 26, "texto": "Como perro que vuelve a su vómito, así es el necio que repite su necedad." }, + { "numero": 27, "texto": "No te jactes del día de mañana, porque no sabes qué dará de sí el día. Alábete el extraño, y no tu propia boca." }, + { "numero": 28, "texto": "El que encubre sus pecados no prosperará; mas el que los confiesa y se aparta alcanzará misericordia." }, + { "numero": 29, "texto": "Cuando los justos se alegran, hay gran gloria; pero cuando los impíos suben, el pueblo gime." }, + { "numero": 30, "texto": "Dos cosas te he demandado; no me las niegues: Aleja de mí la vanidad y la mentira; dame solo lo necesario." }, + { "numero": 31, "texto": "Mujer virtuosa, ¿quién la hallará? Su precio sobrepasa largamente al de las piedras preciosas." }, + { "numero": 32, "texto": "La sabiduría clama en las calles, da su voz en las plazas. ¿Hasta cuándo amaréis la simpleza?" }, + { "numero": 33, "texto": "El corazón alegre es buena medicina; mas el espíritu triste seca los huesos." }, + { "numero": 34, "texto": "Mejor es un bocado seco, y en paz, que casa de contiendas llena de provisiones." }, + { "numero": 35, "texto": "El hierro con el hierro se aguza; y así el hombre aguza el rostro de su amigo." }, + { "numero": 36, "texto": "Más confiable es el que reprende abiertamente que el que lisonjea en secreto." }, + { "numero": 37, "texto": "Como el águila que se remonta, tal es el hombre que está seguro en el temor del Señor." }, + { "numero": 38, "texto": "Donde no hay visión, el pueblo se extravía; pero dichoso el que guarda la ley." }, + { "numero": 39, "texto": "La vara y la corrección dan sabiduría; mas el muchacho consentido avergonzará a su madre." }, + { "numero": 40, "texto": "El pobre y el rico se encuentran; a ambos los hizo el Señor." }, + { "numero": 41, "texto": "No hagas al mal a nadie que en ti confía; no respondas mal al que contigo bien ha hecho." }, + { "numero": 42, "texto": "El hombre sabio es fuerte, y el hombre de conocimiento aumenta el poder." }, + { "numero": 43, "texto": "La sabiduría es mejor que las armas de guerra; pero un solo pecador destruye mucho bien." }, + { "numero": 44, "texto": "El que guarda la ley es hijo prudente; mas el que es compañero de glotones avergüenza a su padre." }, + { "numero": 45, "texto": "Honra al Señor con tus bienes, y con las primicias de todos tus frutos. Así tus graneros estarán llenos." }, + { "numero": 46, "texto": "Bienaventurado el hombre que halla la sabiduría; porque su ganancia es mejor que la de la plata." }, + { "numero": 47, "texto": "No envidies al hombre violento, ni escojas ninguno de sus caminos. Porque el Señor abomina al perverso." }, + { "numero": 48, "texto": "El testigo fiel no mentirá; mas el testigo falso hablará mentiras." }, + { "numero": 49, "texto": "La esperanza que se demora es tormento del corazón; pero árbol de vida es el deseo cumplido." }, + { "numero": 50, "texto": "El camino del necio es derecho en su opinión; mas el que obedece el consejo es sabio." }, + { "numero": 51, "texto": "El orgullo del hombre le acarrea humillación; pero al humilde de espíritu sustenta la honra." }, + { "numero": 52, "texto": "Los que buscan al Señor no carecerán de ningún bien. El temor del Señor prolonga los días." }, + { "numero": 53, "texto": "La justicia engrandece a la nación; mas el pecado es mengua de los pueblos." }, + { "numero": 54, "texto": "En la lengua hay poder de vida y de muerte; los que la aman comerán de sus frutos." }, + { "numero": 55, "texto": "El que es tardo para la ira es grande de entendimiento; mas el que es impaciente de espíritu enaltece la necedad." }, + { "numero": 56, "texto": "El camino del perezoso es como seto de espinos; mas la vereda de los rectos, como una calzada." }, + { "numero": 57, "texto": "El que da al pobre no tendrá pobreza; mas el que aparta sus ojos tendrá muchas maldiciones." }, + { "numero": 58, "texto": "No te alegres cuando caiga tu enemigo, y no se regocije tu corazón cuando tropiece." }, + { "numero": 59, "texto": "Como aguas profundas es el consejo en el corazón del hombre; mas el hombre entendido lo alcanzará." }, + { "numero": 60, "texto": "Muchos hombres proclaman cada uno su propia bondad, pero el hombre de verdad, ¿quién lo hallará?" }, + { "numero": 61, "texto": "El camino del justo es como la luz de la aurora, que va en aumento hasta que el día es perfecto." }, + { "numero": 62, "texto": "Sobre toda cosa guardada, guarda tu corazón; porque de él mana la vida." }, + { "numero": 63, "texto": "No dejes para mañana lo que puedes hacer hoy; los planes del diligente ciertamente son ventajosos." }, + { "numero": 64, "texto": "El rico y el pobre se encuentran; el Señor es el hacedor de todos ellos." }, + { "numero": 65, "texto": "Mejor es adquirir sabiduría que oro preciado; y adquirir inteligencia vale más que la plata." }, + { "numero": 66, "texto": "El que anda en integridad anda seguro; mas el que pervierte sus caminos será quebrantado." }, + { "numero": 67, "texto": "No te jactes de la sabiduría, ni de la valentía, ni de las riquezas; mas alábese en esto el que se hubiere de alabar: en entenderme y conocerme." }, + { "numero": 68, "texto": "Así como el agua refleja el rostro, el corazón del hombre refleja al hombre." }, + { "numero": 69, "texto": "El que reprende al hombre hallará después más gracia que el que lisonjea con la lengua." }, + { "numero": 70, "texto": "Teme al Señor, y apártate del mal; porque esto será medicina para tu cuerpo, y refrigerio para tus huesos." }, + { "numero": 71, "texto": "Dios es refugio del pobre, refugio en el tiempo de angustia. No olvides al menesteroso." }, + { "numero": 72, "texto": "Al necio, en su propia opinión, le parece bien todo lo que hace; mas el sabio escucha consejos." }, + { "numero": 73, "texto": "El vientre del impío no se saciará; mas el alma de los justos será saciada." }, + { "numero": 74, "texto": "Panal de miel son los dichos suaves; suavidad al alma y medicina para los huesos." }, + { "numero": 75, "texto": "El que perdona la ofensa cultiva el amor; el que insiste en la ofensa divide a los amigos." }, + { "numero": 76, "texto": "Mejor es un plato de legumbres donde hay amor, que buey engordado donde hay odio." }, + { "numero": 77, "texto": "Los pensamientos del diligente ciertamente tienden a la abundancia; mas todo el que se apresura alocadamente, de cierto va a la pobreza." }, + { "numero": 78, "texto": "El corazón del hombre traza su rumbo, pero sus pasos los dirige el Señor." }, + { "numero": 79, "texto": "La mentira aborrece a sus víctimas y la adulación hace daño. El testigo verdadero libra las almas." }, + { "numero": 80, "texto": "Sin leña se apaga el fuego, y donde no hay chismoso, cesa la contienda." }, + { "numero": 81, "texto": "Cada uno es recompensado conforme a su justicia; porque el Señor conoce el corazón." }, + { "numero": 82, "texto": "El que fuere soberbio será abatido; pero el de espíritu humilde obtendrá honra." }, + { "numero": 83, "texto": "El que labra su tierra tendrá abundancia de pan; mas el que sigue a los ociosos se llenará de pobreza." }, + { "numero": 84, "texto": "No hay sabiduría, ni inteligencia, ni consejo, contra el Señor." }, + { "numero": 85, "texto": "El que sigue la justicia y la misericordia hallará la vida, la justicia y la honra." }, + { "numero": 86, "texto": "No hagas nada por contienda o por vanagloria; estima a los demás como superiores a ti mismo." }, + { "numero": 87, "texto": "Lo que el impío teme, eso le vendrá; pero a los justos les será dado lo que desean." }, + { "numero": 88, "texto": "Una palabra dicha a su tiempo, ¡cuán buena es! Como manzanas de oro con figuras de plata." }, + { "numero": 89, "texto": "El hombre que no gobierna su espíritu es como ciudad derribada y sin muros." }, + { "numero": 90, "texto": "Dichoso el hombre que siempre teme al Señor; mas el que endurece su corazón caerá en el mal." }, + { "numero": 91, "texto": "Tres cosas me son ocultas; aun tampoco sé la cuarta: el rastro del águila en el aire, el rastro de la serpiente sobre la peña." }, + { "numero": 92, "texto": "No menosprecies a tu madre cuando fuere vieja. Compra la verdad, y no la vendas." }, + { "numero": 93, "texto": "El ojo que escarnece a su padre y menosprecia la instrucción de la madre, lo sacarán los cuervos del valle." }, + { "numero": 94, "texto": "El generoso prosperará; el que da agua, agua recibirá. Como el tú trates a los demás, así serás tratado." }, + { "numero": 95, "texto": "El hombre fiel tendrá muchas bendiciones; mas el que se apresura a enriquecerse no quedará sin castigo." }, + { "numero": 96, "texto": "El que tiene misericordia del pobre, a Dios presta; y él le devolverá su bien." }, + { "numero": 97, "texto": "La soberbia del hombre lo abate; pero al humilde de espíritu lo sustenta la honra." }, + { "numero": 98, "texto": "En todo trabajo hay fruto; mas las vanas palabras de los labios empobrecen." }, + { "numero": 99, "texto": "El corazón del hombre es profundo como el agua; mas el hombre entendido lo sondea." }, + { "numero": 100, "texto": "Mejor es el fin de un asunto que su principio; mejor es el ánimo paciente que el ánimo altivo." } +] diff --git a/src/main/resources/data/santos.json b/src/main/resources/data/santos.json new file mode 100644 index 0000000..263968a --- /dev/null +++ b/src/main/resources/data/santos.json @@ -0,0 +1,73 @@ +{ +"01-01": { "nombre": "Santa María, Madre de Dios", "descripcion": "Solemnidad de la Virgen María, Madre de Dios." }, +"01-02": { "nombre": "San Basilio Magno y San Gregorio Nacianceno", "descripcion": "Obispos y doctores de la Iglesia." }, +"01-03": { "nombre": "Santísimo Nombre de Jesús", "descripcion": "Fiesta del Nombre de Jesús." }, +"01-04": { "nombre": "Santa Ángela de Foligno", "descripcion": "Mística franciscana italiana." }, +"01-05": { "nombre": "San Genovevo Torres", "descripcion": "Fundador de la Congregación de los Hermanos del Sagrado Corazón." }, +"01-06": { "nombre": "Epifanía del Señor", "descripcion": "Manifestación de Jesús a los pueblos (Reyes Magos)." }, +"01-07": { "nombre": "San Raimundo de Peñafort", "descripcion": "Dominico, patrono de los abogados." }, +"01-08": { "nombre": "San Severino", "descripcion": "Abad y evangelizador de Austria." }, +"01-09": { "nombre": "San Eulogio de Córdoba", "descripcion": "Mártir español." }, +"01-10": { "nombre": "San Gonzalo", "descripcion": "Presbítero portugués." }, +"01-11": { "nombre": "Bautismo del Señor", "descripcion": "Fiesta del Bautismo de Jesús en el Jordán." }, +"01-12": { "nombre": "Santa Tatiana", "descripcion": "Mártir romana." }, +"01-13": { "nombre": "San Hilario de Poitiers", "descripcion": "Obispo y doctor de la Iglesia." }, +"01-14": { "nombre": "San Félix de Nola", "descripcion": "Presbítero y mártir." }, +"01-15": { "nombre": "San Mauro", "descripcion": "Discípulo de San Benito." }, +"01-16": { "nombre": "San Marcelo I, Papa", "descripcion": "Papa y mártir." }, +"01-17": { "nombre": "San Antonio Abad", "descripcion": "Patrón de los animales." }, +"01-18": { "nombre": "Santa Prisca", "descripcion": "Mártir romana." }, +"01-19": { "nombre": "San Mario", "descripcion": "Mártir junto a su familia." }, +"01-20": { "nombre": "San Sebastián", "descripcion": "Mártir romano, patrono de los deportistas." }, +"01-21": { "nombre": "Santa Inés", "descripcion": "Virgen y mártir romana." }, +"01-22": { "nombre": "San Vicente", "descripcion": "Mártir español." }, +"01-23": { "nombre": "San Ildefonso de Toledo", "descripcion": "Obispo y escritor." }, +"01-24": { "nombre": "San Francisco de Sales", "descripcion": "Obispo y doctor de la Iglesia." }, +"01-25": { "nombre": "Conversión de San Pablo", "descripcion": "Apóstol de los gentiles." }, +"01-26": { "nombre": "San Timoteo y San Tito", "descripcion": "Obispos y discípulos de San Pablo." }, +"01-27": { "nombre": "Santa Ángela Merici", "descripcion": "Fundadora de las Ursulinas." }, +"01-28": { "nombre": "Santo Tomás de Aquino", "descripcion": "Doctor de la Iglesia, patrono de los estudiantes." }, +"01-29": { "nombre": "San Valero de Zaragoza", "descripcion": "Obispo español." }, +"01-30": { "nombre": "Santa Martina", "descripcion": "Mártir romana." }, +"01-31": { "nombre": "San Juan Bosco", "descripcion": "Fundador de los Salesianos." }, + +"02-01": { "nombre": "San Brígido", "descripcion": "Abad irlandés, patrón de Europa." }, +"02-02": { "nombre": "Presentación del Señor", "descripcion": "Fiesta de la Presentación de Jesús en el Templo." }, +"02-03": { "nombre": "San Blas", "descripcion": "Obispo y mártir, patrón de los enfermos de garganta." }, +"02-04": { "nombre": "Santa Verónica", "descripcion": "Mujer que limpió el rostro de Jesús en el camino al Calvario." }, +"02-05": { "nombre": "San Agatón, Papa", "descripcion": "Papa y mártir." }, +"02-06": { "nombre": "Santa Dorotea", "descripcion": "Mártir romana." }, +"02-07": { "nombre": "San Teodoro de Amasea", "descripcion": "Mártir romano." }, +"02-08": { "nombre": "Santa Josefina Bakhita", "descripcion": "Santa sudanesa, patrona de los refugiados." }, +"02-09": { "nombre": "San Apolinar", "descripcion": "Obispo y mártir." }, +"02-10": { "nombre": "Santa Escolástica", "descripcion": "Hermana de San Benito, fundadora de monasterios femeninos." }, +"02-11": { "nombre": "Nuestra Señora de Lourdes", "descripcion": "Fiesta de la Virgen de Lourdes, patrona de los enfermos." }, +"02-12": { "nombre": "San Eulalio de Mérida", "descripcion": "Mártir español." }, +"02-13": { "nombre": "San Cirilo de Jerusalén", "descripcion": "Obispo y doctor de la Iglesia." }, +"02-14": { "nombre": "San Valentín", "descripcion": "Mártir romano, patrón de los enamorados." }, +"02-15": { "nombre": "San Claudio de Besançon", "descripcion": "Obispo y escritor." }, +"02-16": { "nombre": "Santa Juliana de Nicodemia", "descripcion": "Mártir romana." }, +"02-17": { "nombre": "San Alejandro de Jerusalén", "descripcion": "Mártir romano." }, +"02-18": { "nombre": "Santa Bernadette Soubirous", "descripcion": "Santa francesa, vidente de Lourdes." }, +"02-19": { "nombre": "San Conrado de Piacenza", "descripcion": "Mártir italiano." }, +"02-20": { "nombre": "San Eleuterio", "descripcion": "Mártir romano." }, +"02-21": { "nombre": "San Pedro Damián", "descripcion": "Obispo y doctor de la Iglesia." }, +"02-22": { "nombre": "Cátedra de San Pedro", "descripcion": "Fiesta de la autoridad de San Pedro como cabeza de la Iglesia." }, +"02-23": { "nombre": "San Policarpo de Esmirna", "descripcion": "Mártir y obispo del siglo II." }, +"02-24": { "nombre": "San Modesto de Jerusalén", "descripcion": "Obispo y mártir romano." }, +"02-25": { "nombre": "Santa Walburga", "descripcion": "Abadesa y mística alemana." }, +"02-26": { "nombre": "San Porfirio de Gaza", "descripcion": "Obispo y mártir." }, +"02-27": { "nombre": "San Gabriel de la Dolorosa", "descripcion": "Arcángel, mensajero de Dios." }, +"02-28": { "nombre": "San Romano de Condat", "descripcion": "Abad y fundador de monasterios en Francia." }, +"02-29": { "nombre": "San Osvaldo de Northumbria", "descripcion": "Rey y mártir inglés." }, + +"05-23": { "nombre": "San Desiderio", "descripcion": "" }, +"05-24": { "nombre": "Nuestra Señora, Auxilio de los Cristianos", "descripcion": "Fiesta de la Virgen María, patrona de los cristianos." }, +"05-25": { "nombre": "San Gregorio VII", "descripcion": "Papa y reformador de la Iglesia." }, +"05-26": { "nombre": "San Felipe Neri", "descripcion": "Presbítero y fundador de la Congregación del Oratorio." }, +"05-27": { "nombre": "San Agustín de Canterbury", "descripcion": "Obispo y mártir, primer arzobispo de Canterbury." }, +"05-28": { "nombre": "San Germán de París", "descripcion": "Obispo y santo francés." }, +"05-29": { "nombre": "San Maximiliano Kolbe", "descripcion": "Sacerdote polaco, mártir en Auschwitz." }, +"05-30": { "nombre": "Santa Juana de Arco", "descripcion": "Heroína francesa, mártir y santa." }, +"05-31": { "nombre": "Visita de la Virgen María a su prima Santa Isabel", "descripcion": "Fiesta de la Visitación, conmemorando el encuentro de María con Isabel." } +} \ No newline at end of file diff --git a/src/main/resources/db/init.sql b/src/main/resources/db/init.sql new file mode 100644 index 0000000..9fb0228 --- /dev/null +++ b/src/main/resources/db/init.sql @@ -0,0 +1,366 @@ +INSERT INTO santo_del_dia (fecha, santo, descripcion, color) VALUES +('2026-01-01', 'Santa María, Madre de Dios', NULL, 'rosa'), +('2026-01-02', 'San Basilio Magno y San Gregorio Nacianceno', NULL, 'blanco'), +('2026-01-03', 'Santísimo Nombre de Jesús', NULL, 'blanco'), +('2026-01-04', 'Santa Ángela de Foligno', NULL, 'blanco'), +('2026-01-05', 'San Genovevo Torres', NULL, 'blanco'), +('2026-01-06', 'Epifanía del Señor', NULL, 'rojo'), +('2026-01-07', 'San Raimundo de Peñafort', NULL, 'blanco'), +('2026-01-08', 'San Severino', NULL, 'blanco'), +('2026-01-09', 'San Eulogio de Córdoba', NULL, 'blanco'), +('2026-01-10', 'San Gonzalo', NULL, 'blanco'), +('2026-01-11', 'Bautismo del Señor', NULL, 'blanco'), +('2026-01-12', 'Santa Tatiana', NULL, 'blanco'), +('2026-01-13', 'San Hilario de Poitiers', NULL, 'blanco'), +('2026-01-14', 'San Félix de Nola', NULL, 'blanco'), +('2026-01-15', 'San Mauro', NULL, 'blanco'), +('2026-01-16', 'San Marcelo I, Papa', NULL, 'blanco'), +('2026-01-17', 'San Antonio Abad', 'Patrón de los animales', 'blanco'), +('2026-01-18', 'Santa Prisca', NULL, 'rojo'), +('2026-01-19', 'San Mario', 'y familia', 'blanco'), +('2026-01-20', 'San Sebastián', 'mártir', 'rojo'), +('2026-01-21', 'Santa Inés', 'virgen y mártir', 'rojo'), +('2026-01-22', 'San Vicente', 'mártir', 'rojo'), +('2026-01-23', 'San Ildefonso de Toledo', 'obispo', 'blanco'), +('2026-01-24', 'San Francisco de Sales', 'Doctor de la Iglesia', 'blanco'), +('2026-01-25', 'Conversión de San Pablo', 'apóstol', 'blanco'), +('2026-01-26', 'San Timoteo y San Tito', 'obispos', 'blanco'), +('2026-01-27', 'Santa Ángela Merici', NULL, 'blanco'), +('2026-01-28', 'Santo Tomás de Aquino', 'Doctor de la Iglesia. Patrón de los estudiantes, teólogo, filósofo', 'blanco'), +('2026-01-29', 'San Valero de Zaragoza', NULL, 'blanco'), +('2026-01-30', 'Santa Martina', NULL, 'rojo'), +('2026-01-31', 'San Juan Bosco', 'Fundador de los Salesianos', 'blanco'), +('2026-02-01', 'Santa Brígida', 'Patrona de Europa', 'blanco'), +('2026-02-02', 'Presentación del Señor (Candelaria)', 'La Virgen María y San José presentan al Niño Jesús en el Templo', 'blanco'), +('2026-02-03', 'San Blas', 'Protector de las enfermedades de garganta', 'rojo'), +('2026-02-04', 'San Gilberto', 'obispo', 'blanco'), +('2026-02-05', 'Santa Águeda', 'Patrona de las mujeres', 'rojo'), +('2026-02-06', 'San Pablo Miki', 'y compañeros mártires', 'rojo'), +('2026-02-07', 'San Ricardo', 'mártir', 'rojo'), +('2026-02-08', 'San Jerónimo Emiliani', 'Patrón de los huérfanos', 'blanco'), +('2026-02-09', 'Santa Apolonia', 'mártir', 'rojo'), +('2026-02-10', 'Santa Escolástica', 'hermana de San Benito', 'blanco'), +('2026-02-11', 'Nuestra Señora de Lourdes', 'La Virgen María se apareció en Lourdes a Santa Bernardita', 'blanco'), +('2026-02-12', 'Santa Eulalia de Barcelona', 'virgen y mártir', 'rojo'), +('2026-02-13', 'San Benigno', 'mártir', 'rojo'), +('2026-02-14', 'San Valentín', 'Patrón de los enamorados', 'rojo'), +('2026-02-15', 'San Claudio de la Colombière', 'confesor', 'blanco'), +('2026-02-16', 'San Onésimo', 'esclavo convertido por San Pablo', 'blanco'), +('2026-02-17', 'Los Siete Santos Fundadores', 'de la Orden de los Servitas', 'blanco'), +('2026-02-18', 'Miércoles de Ceniza', 'Inicio de la Cuaresma', 'morado'), +('2026-02-19', 'San Álvaro de Córdoba', 'confesor', 'blanco'), +('2026-02-20', 'San Eleuterio', NULL, 'blanco'), +('2026-02-21', 'San Pedro Damián', 'obispo y doctor de la Iglesia', 'blanco'), +('2026-02-22', 'Cátedra de San Pedro', 'Fiesta de San Pedro, apóstol', 'blanco'), +('2026-02-23', 'San Policarpo', 'obispo y mártir', 'rojo'), +('2026-02-24', 'San Modesto', 'mártir', 'rojo'), +('2026-02-25', 'San Cesáreo de Nazianzo', 'obispo', 'blanco'), +('2026-02-26', 'San Alejandro de Alejandría', 'mártir', 'rojo'), +('2026-02-27', 'San Leandro de Sevilla', 'obispo', 'blanco'), +('2026-02-28', 'San Román', 'mártir', 'rojo'), +('2026-03-01', 'San David de Gales', NULL, 'blanco'), +('2026-03-02', 'San Chad de Mercia', NULL, 'blanco'), +('2026-03-03', 'San Casimiro', 'Patrón de Polonia', 'blanco'), +('2026-03-04', 'San Lucio I, Papa', NULL, 'rojo'), +('2026-03-05', 'San Adrián de Nicomedia', NULL, 'rojo'), +('2026-03-06', 'San Coleta de Corbie', NULL, 'blanco'), +('2026-03-07', 'San Perpetuo y San Feliciano', NULL, 'rojo'), +('2026-03-08', 'San Juan de Dios', 'Patrón de los hospitales', 'blanco'), +('2026-03-09', 'San Francescó de Borgia', NULL, 'blanco'), +('2026-03-10', 'San Macario de Alejandría', NULL, 'blanco'), +('2026-03-11', 'San Eulogio de Córdoba', NULL, 'rojo'), +('2026-03-12', 'San Gregorio Nacianceno', NULL, 'blanco'), +('2026-03-13', 'Santa Luisa de Marillac', NULL, 'blanco'), +('2026-03-14', 'San Matías', 'apóstol', 'rojo'), +('2026-03-15', 'San Longino', NULL, 'rojo'), +('2026-03-16', 'Santa Juana de Chantal', NULL, 'blanco'), +('2026-03-17', 'San Patricio', 'Patrón de Irlanda', 'blanco'), +('2026-03-18', 'San Cirilo de Jerusalén', NULL, 'blanco'), +('2026-03-19', 'San José', 'Esposo de la Virgen María', 'blanco'), +('2026-03-20', 'San Cándido', 'mártir', 'rojo'), +('2026-03-21', 'Santa Benedicta de la Cruz', NULL, 'rojo'), +('2026-03-22', 'San León I, Papa', NULL, 'blanco'), +('2026-03-23', 'San Turibio de Mogrovejo', NULL, 'blanco'), +('2026-03-24', 'San Gabriel de la Dolorosa', NULL, 'blanco'), +('2026-03-25', 'Anunciación del Señor', 'El angel se apareció a la Virgen María', 'blanco'), +('2026-03-26', 'San Ezequiel Moreno', NULL, 'blanco'), +('2026-03-27', 'San Ruperto', NULL, 'blanco'), +('2026-03-28', 'San Guntrán', NULL, 'blanco'), +('2026-03-29', 'San Bertoldo', NULL, 'blanco'), +('2026-03-30', 'San Amando de Maastricht', NULL, 'blanco'), +('2026-03-31', 'San Benedicto José Labre', NULL, 'blanco'), +('2026-04-01', 'San Hugo de Grenoble', NULL, 'blanco'), +('2026-04-02', 'San Francisco de Paula', NULL, 'blanco'), +('2026-04-03', 'San Ricardo Pampuri', NULL, 'blanco'), +('2026-04-04', 'San Isidoro de Sevilla', NULL, 'blanco'), +('2026-04-05', 'San Vicente Ferrer', NULL, 'blanco'), +('2026-04-06', 'San Marcelino Champagnat', NULL, 'blanco'), +('2026-04-07', 'San Juan Bautista de la Salle', NULL, 'blanco'), +('2026-04-08', 'San Dionisio', '(obispo) y compañeros mártires', 'rojo'), +('2026-04-09', 'San Casimiro', NULL, 'blanco'), +('2026-04-10', 'San Ezequiel Moreno', NULL, 'blanco'), +('2026-04-11', 'San Esteban I', 'Papa y mártir', 'rojo'), +('2026-04-12', 'San León IX', 'Papa', 'blanco'), +('2026-04-13', 'San Hermenegildo', NULL, 'rojo'), +('2026-04-14', 'San Matías', 'apóstol', 'rojo'), +('2026-04-15', 'San Dámaso I', 'Papa', 'blanco'), +('2026-04-16', 'San Bernabé', 'apóstol', 'rojo'), +('2026-04-17', 'San Aniceto', 'Papa y mártir', 'rojo'), +('2026-04-18', 'San Apuleyo', NULL, 'blanco'), +('2026-04-19', 'San Expedito', NULL, 'rojo'), +('2026-04-20', 'San Jorge', 'mártir', 'rojo'), +('2026-04-21', 'San Anselmo de Canterbury', NULL, 'blanco'), +('2026-04-22', 'San Soter y San Calixto', 'Papas y mártires', 'rojo'), +('2026-04-23', 'San Jorge', 'mártir', 'rojo'), +('2026-04-24', 'San Fidel de Sigmaringa', NULL, 'rojo'), +('2026-04-25', 'San Marcos', 'evangelista', 'rojo'), +('2026-04-26', 'San Pedro de Verona', NULL, 'rojo'), +('2026-04-27', 'San Zita', NULL, 'blanco'), +('2026-04-28', 'San Luis María Grignion de Montfort', NULL, 'blanco'), +('2026-04-29', 'San Pedro Chanel', NULL, 'rojo'), +('2026-04-30', 'San Pío V', 'Papa', 'blanco'), +('2026-05-01', 'San José Obrero', NULL, 'blanco'), +('2026-05-02', 'San Atanasio', NULL, 'blanco'), +('2026-05-03', 'San Felipe y Santiago', 'apóstoles', 'rojo'), +('2026-05-04', 'San Florencio de Orange', NULL, 'blanco'), +('2026-05-05', 'San Hilario de Arlés', NULL, 'blanco'), +('2026-05-06', 'San Juan de Ávila', NULL, 'blanco'), +('2026-05-07', 'San Esteban de Hungría', 'Rey de Hungría', 'blanco'), +('2026-05-08', 'San Miguel Garicoits', NULL, 'blanco'), +('2026-05-09', 'San Gregorio Magno', NULL, 'blanco'), +('2026-05-10', 'San Antonino de Florencia', NULL, 'blanco'), +('2026-05-11', 'San Ignacio de Loyola', 'Fundador de la Compañía de Jesús', 'blanco'), +('2026-05-12', 'Santa Nereida', NULL, 'blanco'), +('2026-05-13', 'Nuestra Señora de Fátima', 'La Virgen María se apareció en Fátima a tres pastorcitos', 'blanco'), +('2026-05-14', 'San Matías', 'apóstol', 'rojo'), +('2026-05-15', 'San Isidro Labrador', 'Patrón de los agricultores', 'blanco'), +('2026-05-16', 'San Juan Nepomuceno', NULL, 'rojo'), +('2026-05-17', 'San Pasquale Baylón', NULL, 'blanco'), +('2026-05-18', 'San Venancio', NULL, 'rojo'), +('2026-05-19', 'San Celestino V', 'Papa', 'blanco'), +('2026-05-20', 'San Bernardino de Siena', NULL, 'blanco'), +('2026-05-21', 'Santa María Magdalena de Pazzi', NULL, 'blanco'), +('2026-05-22', 'Santa Rita de Casia', NULL, 'blanco'), +('2026-05-23', 'San Desiderio', NULL, 'rojo'), +('2026-05-24', 'Nuestra Señora, Auxilio de los Cristianos', NULL, 'blanco'), +('2026-05-25', 'San Gregorio VII', 'Papa', 'blanco'), +('2026-05-26', 'San Felipe Neri', NULL, 'blanco'), +('2026-05-27', 'San Agustín de Cantorbery', NULL, 'blanco'), +('2026-05-28', 'San Germán de París', NULL, 'blanco'), +('2026-05-29', 'San Maximiliano Kolbe', NULL, 'rojo'), +('2026-05-30', 'Santa Juana de Arco', NULL, 'blanco'), +('2026-05-31', 'Visita de la Virgen María a su prima Santa Isabel', NULL, 'blanco'), +('2026-06-01', 'San Justino Mártir', NULL, 'rojo'), +('2026-06-02', 'San Marcelino de París', NULL, 'blanco'), +('2026-06-03', 'Santos Carlos Lwanga y compañeros mártires', NULL, 'rojo'), +('2026-06-04', 'San Francisco Caracciolo', NULL, 'blanco'), +('2026-06-05', 'San Bonifacio M. de Ligorio', NULL, 'rojo'), +('2026-06-06', 'San Norberto', NULL, 'blanco'), +('2026-06-07', 'San Roberto Belarmino', NULL, 'blanco'), +('2026-06-08', 'San Medardo', NULL, 'blanco'), +('2026-06-09', 'San Efrén', NULL, 'blanco'), +('2026-06-10', 'San Guillermo de Vercelli', NULL, 'blanco'), +('2026-06-11', 'San Bernabé, apóstol', NULL, 'rojo'), +('2026-06-12', 'Santos Juan y Pablo, mártires', NULL, 'rojo'), +('2026-06-13', 'San Antonio de Padua', 'Doctor de la Iglesia', 'blanco'), +('2026-06-14', 'San Elías Profeta', NULL, 'blanco'), +('2026-06-15', 'San Vito', 'y compañeros mártires', 'rojo'), +('2026-06-16', 'San Juan Francisco Régis', NULL, 'blanco'), +('2026-06-17', 'San Alberto Chmielowski', NULL, 'blanco'), +('2026-06-18', 'San Gregorio Barbarigo', NULL, 'blanco'), +('2026-06-19', 'Santo Romualdo', 'y compañeros monjes', 'blanco'), +('2026-06-20', 'San Silverio', 'Papa y mártir', 'rojo'), +('2026-06-21', 'San Luis Gonzaga', NULL, 'blanco'), +('2026-06-22', 'Santa Paulina', NULL, 'blanco'), +('2026-06-23', 'San José Cafasso', NULL, 'blanco'), +('2026-06-24', 'Natividad de San Juan Bautista', 'Nacimiento de San Juan Bautista', 'blanco'), +('2026-06-25', 'Santos Cirilo y Metodio', NULL, 'blanco'), +('2026-06-26', 'San José María de Yermo y Parres', NULL, 'blanco'), +('2026-06-27', 'San Ladislao', NULL, 'blanco'), +('2026-06-28', 'San Ireneo', 'obispo y mártir', 'rojo'), +('2026-06-29', 'San Pedro y San Pablo', 'apóstoles', 'rojo'), +('2026-06-30', 'San Justo de Alcalá', NULL, 'rojo'), +('2026-07-01', 'Santa María Goretti', NULL, 'rojo'), +('2026-07-02', 'San Martín de Porres', NULL, 'blanco'), +('2026-07-03', 'Santos Tomás y Feliciano', 'mártires', 'rojo'), +('2026-07-04', 'San Ulrico de Augsburgo', NULL, 'blanco'), +('2026-07-05', 'San Antonio María Zaccaria', NULL, 'blanco'), +('2026-07-06', 'San María Isabel de la Trinidad', NULL, 'blanco'), +('2026-07-07', 'San Fermin', NULL, 'blanco'), +('2026-07-08', 'San Procopio', NULL, 'rojo'), +('2026-07-09', 'San Agustín Zhao Rong y compañeros mártires', NULL, 'rojo'), +('2026-07-10', 'San Benito', 'Abad. Fundador de la Orden Benedictina. Medalla de San Benito', 'blanco'), +('2026-07-11', 'San Juan Bautista de la Salle', NULL, 'blanco'), +('2026-07-12', 'San Nabor y San Félix', 'mártires', 'rojo'), +('2026-07-13', 'San Enrique', NULL, 'blanco'), +('2026-07-14', 'San Camilo de Lelis', NULL, 'blanco'), +('2026-07-15', 'Santa María Gorretti', NULL, 'rojo'), +('2026-07-16', 'Nuestra Señora del Carmen', 'Patrona de los Carmelitas y los pescadores. Escapulario', 'blanco'), +('2026-07-17', 'San Alejo', NULL, 'blanco'), +('2026-07-18', 'San Camilo de Lelis', NULL, 'blanco'), +('2026-07-19', 'San Vicente de Paúl', NULL, 'blanco'), +('2026-07-20', 'San Apolinario', NULL, 'rojo'), +('2026-07-21', 'San Lorenzo de Brindis', NULL, 'blanco'), +('2026-07-22', 'Santa María Magdalena', 'la apóstol de los apóstoles', 'blanco'), +('2026-07-23', 'Santos Apeles y Clemente', 'mártires', 'rojo'), +('2026-07-24', 'San Cristóbal Magallanes y compañeros', 'mártires', 'rojo'), +('2026-07-25', 'Santiago', 'apóstol', 'rojo'), +('2026-07-26', 'San Joaquín y Santa Ana', NULL, 'blanco'), +('2026-07-27', 'Santa Marta', NULL, 'blanco'), +('2026-07-28', 'San Pedro Crisólogo', NULL, 'blanco'), +('2026-07-29', 'Santa María de los Ángeles', NULL, 'blanco'), +('2026-07-30', 'San Abdon y San Sennen', 'mártires', 'rojo'), +('2026-07-31', 'San Ignacio de Loyola', NULL, 'blanco'), +('2026-08-01', 'San Alfonso María de Ligorio', NULL, 'blanco'), +('2026-08-02', 'Santa Eusebia', NULL, 'blanco'), +('2026-08-03', 'San Lamberto', 'obispo y mártir', 'rojo'), +('2026-08-04', 'San Juan María Vianney', NULL, 'blanco'), +('2026-08-05', 'Dedicatoria de la Basílica de Letrán', NULL, 'blanco'), +('2026-08-06', 'Transfiguración del Señor', NULL, 'blanco'), +('2026-08-07', 'San Cajetano', NULL, 'blanco'), +('2026-08-08', 'San Dominico', NULL, 'blanco'), +('2026-08-09', 'San Román', NULL, 'rojo'), +('2026-08-10', 'San Lorenzo', 'diácono y mártir', 'rojo'), +('2026-08-11', 'Santa Clara de Asís', NULL, 'blanco'), +('2026-08-12', 'San Maximiliano Kolbe', NULL, 'rojo'), +('2026-08-13', 'San Poncio', 'mártir', 'rojo'), +('2026-08-14', 'San Maximiliano Kolbe', NULL, 'rojo'), +('2026-08-15', 'Asunción de la Virgen María', NULL, 'blanco'), +('2026-08-16', 'San Esteban de Hungría', NULL, 'blanco'), +('2026-08-17', 'San Jacinto', NULL, 'blanco'), +('2026-08-18', 'San Alberto Hurtado', NULL, 'blanco'), +('2026-08-19', 'San Juan Eudes', NULL, 'blanco'), +('2026-08-20', 'San Bernardo de Claraval', NULL, 'blanco'), +('2026-08-21', 'San Pío X, Papa', NULL, 'blanco'), +('2026-08-22', 'Santa María Reina', NULL, 'blanco'), +('2026-08-23', 'San Rosa de Lima', NULL, 'blanco'), +('2026-08-24', 'San Bartolomé', 'apóstol', 'rojo'), +('2026-08-25', 'San Luis IX', 'rey de Francia', 'blanco'), +('2026-08-26', 'San José de Calasanz', NULL, 'blanco'), +('2026-08-27', 'Santa Mónica', NULL, 'blanco'), +('2026-08-28', 'San Agustín', 'obispo y doctor de la Iglesia. Fundador de los agustinos', 'blanco'), +('2026-08-29', 'Martirio de San Juan Bautista', NULL, 'rojo'), +('2026-08-30', 'Santa Rosa de Lima', NULL, 'blanco'), +('2026-08-31', 'San Ramón Nonato', 'santo de las parturientas', 'blanco'), +('2026-09-01', 'San Egidio', 'abate', 'blanco'), +('2026-09-02', 'Santa María de la Cabeza', NULL, 'blanco'), +('2026-09-03', 'San Gregorio Magno', NULL, 'blanco'), +('2026-09-04', 'San Rosendo', NULL, 'blanco'), +('2026-09-05', 'Santa Teresa de Calcuta', NULL, 'blanco'), +('2026-09-06', 'San Zacarías, profeta', NULL, 'blanco'), +('2026-09-07', 'San Cayetano', NULL, 'blanco'), +('2026-09-08', 'Natividad de la Virgen María', NULL, 'blanco'), +('2026-09-09', 'San Pedro Claver', NULL, 'blanco'), +('2026-09-10', 'San Nicolás de Tolentino', NULL, 'blanco'), +('2026-09-11', 'San Juan Gabriel Perboyre', NULL, 'rojo'), +('2026-09-12', 'Santísimo Nombre de María', NULL, 'blanco'), +('2026-09-13', 'San Juan Crisóstomo, obispo y doctor de la Iglesia', NULL, 'blanco'), +('2026-09-14', 'Exaltación de la Santa Cruz', NULL, 'rojo'), +('2026-09-15', 'Nuestra Señora de los Dolores', NULL, 'blanco'), +('2026-09-16', 'San Cornelio, Papa y San Cipriano, obispo, mártires', NULL, 'rojo'), +('2026-09-17', 'San Roberto Bellarmino', NULL, 'blanco'), +('2026-09-18', 'San José de Cupertino', NULL, 'blanco'), +('2026-09-19', 'San Januario, obispo y mártir', NULL, 'rojo'), +('2026-09-20', 'San Andrés Kim Taegon y compañeros mártires', NULL, 'rojo'), +('2026-09-21', 'San Mateo, apóstol y evangelista', NULL, 'rojo'), +('2026-09-22', 'San Maurilio', NULL, 'blanco'), +('2026-09-23', 'San Pío de Pietrelcina', NULL, 'blanco'), +('2026-09-24', 'Nuestra Señora de la Merced', NULL, 'blanco'), +('2026-09-25', 'San Cleofás', NULL, 'blanco'), +('2026-09-26', 'San Cosme y San Damián, mártires', NULL, 'rojo'), +('2026-09-27', 'San Vicente de Paúl', NULL, 'blanco'), +('2026-09-28', 'San Wenceslao', NULL, 'rojo'), +('2026-09-29', 'Santos Arcángeles Miguel, Gabriel y Rafael', NULL, 'blanco'), +('2026-09-30', 'San Jerónimo, sacerdote y doctor de la Iglesia', NULL, 'blanco'), +('2026-10-01', 'Santa Teresa de Lisieux', NULL, 'blanco'), +('2026-10-02', 'Ángel de la Guarda', NULL, 'blanco'), +('2026-10-03', 'San Gerardo Majella', NULL, 'blanco'), +('2026-10-04', 'San Francisco de Asís', NULL, 'rojo'), +('2026-10-05', 'Santa Faustina Kowalska', NULL, 'blanco'), +('2026-10-06', 'San Bruno', NULL, 'blanco'), +('2026-10-07', 'Nuestra Señora del Rosario', NULL, 'blanco'), +('2026-10-08', 'San Dionisio y compañeros mártires', NULL, 'rojo'), +('2026-10-09', 'San Juan Leonardi', NULL, 'blanco'), +('2026-10-10', 'San Daniel Comboni', NULL, 'blanco'), +('2026-10-11', 'San Juan XXIII, Papa', NULL, 'blanco'), +('2026-10-12', 'Nuestra Señora del Pilar', NULL, 'blanco'), +('2026-10-13', 'San Eduardo el Confesor', NULL, 'blanco'), +('2026-10-14', 'San Calixto I, Papa y mártir', NULL, 'rojo'), +('2026-10-15', 'Santa Teresa de Ávila, virgen y doctora de la Iglesia', NULL, 'blanco'), +('2026-10-16', 'San Gerardo de Brogne', NULL, 'blanco'), +('2026-10-17', 'San Ignacio de Antioquía, obispo y mártir', NULL, 'rojo'), +('2026-10-18', 'San Lucas, evangelista', NULL, 'rojo'), +('2026-10-19', 'San Pablo de la Cruz', NULL, 'rojo'), +('2026-10-20', 'San Juan de Capistrano', NULL, 'blanco'), +('2026-10-21', 'San Hilarión', NULL, 'blanco'), +('2026-10-22', 'San Juan Pablo II, Papa', NULL, 'blanco'), +('2026-10-23', 'San Juan de Brébeuf y San Isaac Jogues, sacerdotes y compañeros mártires', NULL, 'rojo'), +('2026-10-24', 'San Antonio María Claret', NULL, 'blanco'), +('2026-10-25', 'San Crispín y San Crispiniano, mártires', NULL, 'rojo'), +('2026-10-26', 'San Evaristo, Papa y mártir', NULL, 'rojo'), +('2026-10-27', 'San Frumencio', NULL, 'blanco'), +('2026-10-28', 'San Simón y San Judas, apóstoles', NULL, 'rojo'), +('2026-10-29', 'San Narciso de Jerusalén', NULL, 'blanco'), +('2026-10-30', 'San Andrés Avellino', NULL, 'blanco'), +('2026-10-31', 'San Wolfgang de Ratisbona', NULL, 'blanco'), +('2026-11-01', 'Todos los Santos', 'Solemnidad nacional', 'blanco'), +('2026-11-02', 'Conmemoración de los Fieles Difuntos', NULL, 'negro'), +('2026-11-03', 'San Martín de Porres', 'Fray Escoba', 'blanco'), +('2026-11-04', 'San Carlos Borromeo', 'obispo', 'blanco'), +('2026-11-05', 'Santa Ángela de la Cruz', 'Fundadora de las Hermanas de la Cruz', 'blanco'), +('2026-11-06', 'Santos Mártires del siglo XX en España', NULL, 'rojo'), +('2026-11-07', 'San Ernesto', 'abad y mártir', 'rojo'), +('2026-11-08', 'San Diosdado', 'Papa', 'blanco'), +('2026-11-09', 'Nuestra Señora de la Almudena', 'Patrona de Madrid', 'blanco'), +('2026-11-10', 'San León Magno', 'Papa y doctor de la Iglesia', 'blanco'), +('2026-11-11', 'San Martín de Tours', 'Patrón de los soldados', 'blanco'), +('2026-11-12', 'San Millán de la Cogolla', 'Patrón de Castilla y copatrón de España', 'blanco'), +('2026-11-13', 'San Leandro de Sevilla', 'obispo', 'blanco'), +('2026-11-14', 'San Serapio', 'mártir de la Orden de la Merced', 'rojo'), +('2026-11-15', 'San Alberto Magno', 'doctor de la Iglesia y patrón de los científicos', 'blanco'), +('2026-11-16', 'Santa Margarita de Escocia', NULL, 'blanco'), +('2026-11-17', 'Santa Isabel de Hungría', NULL, 'blanco'), +('2026-11-18', 'Dedicación de las Basílicas de San Pedro y San Pablo', NULL, 'blanco'), +('2026-11-19', 'San Crispín de Écija', 'obispo y mártir', 'rojo'), +('2026-11-20', 'San Octavio', 'mártir', 'rojo'), +('2026-11-21', 'Presentación de la Virgen María', NULL, 'blanco'), +('2026-11-22', 'Santa Cecilia', 'Patrona de la música', 'rojo'), +('2026-11-23', 'San Clemente I', 'Papa y mártir', 'rojo'), +('2026-11-24', 'San Andrés Dung-Lac y compañeros', 'mártires', 'rojo'), +('2026-11-25', 'Santa Catalina de Alejandría', 'virgen y mártir', 'rojo'), +('2026-11-26', 'San Silvestre', 'abad', 'blanco'), +('2026-11-27', 'San José de Calasanz', 'Patrón de los maestros (fiesta en España)', 'blanco'), +('2026-11-28', 'San Esteban el Joven', 'mártir', 'rojo'), +('2026-11-29', 'San Saturnino', 'mártir y patrón de Pamplona', 'rojo'), +('2026-11-30', 'San Andrés', 'apóstol', 'rojo'), +('2026-12-01', 'San Castritiano', 'obispo', 'blanco'), +('2026-12-02', 'Santa Bibiana', 'virgen y mártir', 'rojo'), +('2026-12-03', 'San Francisco Javier', 'Patrón de Navarra y de las misiones', 'blanco'), +('2026-12-04', 'Santa Bárbara', 'Patrona de la artillería y mineros', 'rojo'), +('2026-12-05', 'San Sabas', 'abad', 'blanco'), +('2026-12-06', 'San Nicolás de Bari', 'obispo', 'blanco'), +('2026-12-07', 'San Ambrosio', 'doctor de la Iglesia', 'blanco'), +('2026-12-08', 'Inmaculada Concepción', 'Patrona de España', 'azul'), +('2026-12-09', 'Santa Leocadia', 'Patrona de Toledo', 'rojo'), +('2026-12-10', 'Nuestra Señora de Loreto', 'Patrona de la aviación', 'blanco'), +('2026-12-11', 'San Dámaso I', 'Papa de origen español', 'blanco'), +('2026-12-12', 'Nuestra Señora de Guadalupe', 'Patrona de Extremadura y de la Hispanidad', 'blanco'), +('2026-12-13', 'Santa Lucía', 'virgen y mártir. Patrona de la vista', 'rojo'), +('2026-12-14', 'San Juan de la Cruz', 'doctor de la Iglesia', 'blanco'), +('2026-12-15', 'Santa Cristiana', NULL, 'blanco'), +('2026-12-16', 'San Modesto', 'obispo', 'blanco'), +('2026-12-17', 'San Lázaro', 'amigo del Señor', 'blanco'), +('2026-12-18', 'Nuestra Señora de la Esperanza', 'La Expectación del Parto', 'blanco'), +('2026-12-19', 'San Urbano V', 'Papa', 'blanco'), +('2026-12-20', 'San Domingo de Silos', 'abad español', 'blanco'), +('2026-12-21', 'San Pedro Canisio', 'doctor de la Iglesia', 'blanco'), +('2026-12-22', 'San Demetrio', 'mártir', 'rojo'), +('2026-12-23', 'San Juan Kanty', 'presbítero', 'blanco'), +('2026-12-24', 'Nochebuena', 'Vigilia de Navidad', 'blanco'), +('2026-12-25', 'Natividad del Señor', 'Solemnidad', 'blanco'), +('2026-12-26', 'San Esteban', 'Protomártir', 'rojo'), +('2026-12-27', 'San Juan Evangelista', 'Apóstol', 'blanco'), +('2026-12-28', 'Santos Inocentes', 'mártires', 'rojo'), +('2026-12-29', 'Santo Tomás Becket', 'obispo y mártir', 'rojo'), +('2026-12-30', 'La Sagrada Familia', 'Jesús, María y José', 'blanco'), +('2026-12-31', 'San Silvestre I', 'Papa', 'blanco'); \ No newline at end of file diff --git a/src/main/resources/static/css/estilos.css b/src/main/resources/static/css/estilos.css new file mode 100644 index 0000000..0fbedcb --- /dev/null +++ b/src/main/resources/static/css/estilos.css @@ -0,0 +1,685 @@ +/* Fuentes importadas corregidas */ +@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,600;1,400&family=Nunito:wght@400;600&display=swap'); + +:root { + /* ── Paleta del header (oscura / litúrgica) ── */ + --color-fondo: #0D1B2E; /* Azul noche profundo */ + --color-tarjeta: #FDFAF3; /* Azul mariano oscuro */ + --color-primario: #2B5BA8; /* Azul mariano medio */ + --color-hover: #1A3F7A; /* Azul mariano hover */ + --color-secundario: #1E3560; /* Azul medio-oscuro */ + --color-borde: #2D4A7A; /* Borde azulado */ + --color-acento: #C9A84C; /* Dorado litúrgico */ + --color-texto-header:#D8E4F5; /* Texto header */ + --color-texto-suave: #6B5040; /* Texto general */ + --color-texto: #2A1C10; /* Texto general oscuro */ + --blanco-puro: #FFFFFF; + --sombra: rgba(0, 0, 0, 0.45); + --color-santo: var(--blanco-puro); + + /* ── Paleta del cuerpo (pergamino / libro antiguo) ── */ + --body-fondo: #F4EFE4; /* Pergamino cálido */ + --body-tarjeta: #FDFAF3; /* Crema suave */ + --body-texto: #2A1C10; /* Sepia oscuro */ + --body-texto-suave: #6B5040; /* Sepia medio */ + --body-borde: #D5C9AC; /* Beige dorado */ + --body-sombra: rgba(0, 0, 0, 0.09); + + /* Colores litúrgicos para el indicador del día */ + --color-liturgico-verde: #2d5a27; + --color-liturgico-rojo: #7a1e1e; + --color-liturgico-violeta:#4b2e5c; + --color-liturgico-blanco: #f0e9d2; + --color-liturgico-azul: #1a3f7a; + --color-liturgico-rosa: #f49ac2; + --color-liturgico-morado: #2e0854; + --color-liturgico-morado-negro: #2e0854; + --color-liturgico-violeta: #9932CC; +} + +body { + margin: 0; + font-family: 'Nunito', sans-serif; + background-color: var(--body-fondo); + color: var(--body-texto); + line-height: 1.6; +} + +/* --- CABECERA --- */ +.header-hoy { + color: var(--color-texto); + text-align: center; + min-height: 160px; + padding: 1rem 2rem 0.8rem; + background-color: var(--color-fondo); /* Más oscuro que el cuerpo */ + border-bottom: 1px solid var(--color-borde); + transition: background-color 0.8s ease; + position: relative; +} + +.titulo { + font-family: 'EB Garamond', serif; + margin: 0; + font-size: 1.9rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 6px; + color: var(--color-tarjeta); + text-shadow: 1px 1px 6px rgba(0,0,0,0.6); +} + +.fecha { + letter-spacing: 2px; + font-size: 0.95rem; + margin-top: 0.3rem; + font-family: 'EB Garamond', serif; + opacity: 0.85; + color: var(--color-texto-header); +} + +.ciclo { + letter-spacing: 2px; + margin-top: 0.2rem; + font-family: 'EB Garamond', serif; + color: var(--color-texto-header); +} + +#indicador-liturgico { + margin:1%; + display: inline-flex; + align-items: center; + background: rgba(255,255,255,0.06); + padding: 5px; + border-radius: 50px; + font-weight: 600; + font-size: 0.85rem; + border: 1px solid rgba(255,255,255,0.1); + color: var(--color-texto-header); +} + +.color-dia { + display: inline-block; + width: 12px; + height: 12px; + border-radius: 50%; + border: 2px solid rgba(255,255,255,0.3); + flex-shrink: 0; +} + +/* --- BLOQUE DEL SANTO --- */ +.santo { + letter-spacing: 2px; + position: relative; + z-index: 10; +} + +.santo h2 { + font-family: 'EB Garamond', serif; + margin: 0; + font-size: 1.6rem; + color: var(--color-santo); +} + +#descripcion-santo-del-dia { + margin-top: 5px; + font-size: 0.95rem; + font-style: italic; + color: var(--color-santo); +} + +.santo_discreto { + font-size: 0.9rem; + margin-top: 0.5rem; + font-family: 'EB Garamond', serif; + font-style: italic; + opacity: 0.9; +} + +.santo_discreto #descripcion-santo-del-dia { + margin-top: 0px; + font-size: 0.9rem; + font-style: italic; + color: var(--color-texto-suave); +} + +.nombre-difunto { + font-weight: 600; + color: var(--color-primario); + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +/* --- MENÚ PRINCIPAL --- */ +.menu-principal { + background-color: var(--color-cabecera); + display: flex; + justify-content: center; + gap: 5rem; + padding: 10px 0; + margin: 0; +} + +.menu-principal a { + color: var(--blanco-puro); + text-decoration: none; + font-weight: 600; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 2px; + transition: color 0.3s ease; +} + +.menu-toggle { + display: none; + font-size: 2rem; + background: none; + border: none; + color: inherit; + cursor: pointer; +} + +@media (max-width: 768px) { + .menu-toggle { + display: block; + margin-left: auto; + margin-right: autoc; + } + .menu-principal { + display: none; + flex-direction: column; + background-color: inherit; + padding: 1rem; + border-top: 1px solid rgba(255,255,255,0.3); + } + .menu-principal.activo { + display: flex; + } + .menu-principal a { + padding: 0.5rem 0; + font-size: 1.2rem; + } +} + +/* --- BLOQUES DE CONTENIDO --- */ +.bloque { + background-color: var(--body-tarjeta); + margin: 2rem auto; + padding: 2rem; + max-width: 600px; + border-radius: 15px; + box-shadow: 0 4px 20px var(--body-sombra); + border: 1px solid var(--body-borde); + text-align: center; +} + +/* --- DIFUNTOS EN PORTADA --- */ +.lista-difuntos-index { + list-style: none; + padding: 0; + margin: 0.5rem 0 0; + display: flex; + flex-direction: column; + gap: 0.3rem; +} + +.lista-difuntos-index li { + font-size: 0.9rem; + color: var(--color-texto-suave); + padding: 0.2rem 0; +} + +.anio-difunto { + font-size: 0.8rem; + opacity: 0.7; +} + +/* --- AJUSTES PARA BLOQUES CON IMAGEN 4:5 --- */ +.bloque-fondo { + /* Quitamos el padding del contenedor para que la capa oscura llegue a los bordes */ + padding: 0 !important; + background-size: cover; + background-position: center top; + background-repeat: no-repeat; + position: relative; + color: var(--blanco-puro); + border-radius: 15px; + overflow: hidden; + + /* Proporción 4:5 - Ajustamos altura mínima para lucir la imagen */ + min-height: 450px; + display: flex; + flex-direction: column; + justify-content: flex-end; /* Texto abajo para no tapar caras/arte arriba */ + max-width: 600px; + margin: 2rem auto; + border: 2px solid var(--color-acento); +} + +.capa-oscura { + /* Graduado: de negro muy sólido abajo a transparente arriba */ + background: linear-gradient(to top, + rgba(0,0,0,0.9) 0%, + rgba(0,0,0,0.4) 50%, + transparent 100%); + padding: 2.5rem 1.5rem 1.5rem 1.5rem; + width: 100%; + box-sizing: border-box; +} + +.bloque-fondo h3 { + font-family: 'EB Garamond', serif; + /* Reducido de 5rem a 2.5rem para que sea elegante y no tape la imagen */ + font-size: 2.5rem !important; + font-weight: 600; + margin: 0 0 0.5rem 0; + color: var(--blanco-puro); + text-shadow: 2px 2px 8px rgba(0,0,0,0.8); +} + +.bloque-fondo p { + font-family: 'Nunito', sans-serif; + font-size: 1.1rem; + margin-bottom: 1.5rem; + text-shadow: 1px 1px 4px rgba(0,0,0,0.8); +} + +.bloque-fondo .boton { + background-color: var(--color-acento); /* Dorado para que resalte más */ + color: var(--color-primario); + border: none; +} + +.bloque-fondo .boton:hover { + background-color: var(--blanco-puro); + color: var(--color-primario); +} + +/* --- SALMO DEL DÍA --- */ +.salmo { + font-family: 'EB Garamond', serif; + font-size: 1.6rem; + line-height: 1.4; + font-style: italic; + color: var(--body-texto); + margin: 0; +} + +.bloque h3 { + font-family: 'EB Garamond', serif; + color: var(--color-acento); + font-size: 1.4rem; + margin-top: 0; +} + +.bloque p { + color: var(--body-texto-suave); +} + +.bloque ul { + list-style: none; + padding: 0; + margin: 1.5rem 0; +} + +.bloque li { + margin-bottom: 12px; + position: relative; + padding-left: 5px; +} + +/* --- BOTONES --- */ +.boton { + display: inline-block; + background-color: var(--color-primario); + color: white; + padding: 12px 25px; + text-decoration: none; + border-radius: 50px; + font-weight: 600; + text-transform: uppercase; + font-size: 0.8rem; + letter-spacing: 1px; + transition: transform 0.2s, background-color 0.2s; +} + +.boton:hover { + transform: translateY(-2px); + background-color: var(--color-hover); +} + +.recursos { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 15px; + padding: 2rem; +} + +.recursos a { + background: transparent; + color: var(--color-primario); + padding: 10px 15px; + border-radius: 8px; + text-decoration: none; + font-size: 0.9rem; + font-weight: 600; + border: 1px solid var(--color-primario); + transition: background 0.2s, color 0.2s; +} + +.recursos a:hover { + background: var(--color-primario); + color: var(--blanco-puro); +} + +.contenedor_rosario { + background: var(--body-tarjeta); + border-radius: 20px; + padding: 2.5rem; + box-shadow: 0 15px 35px var(--body-sombra); + border: 1px solid var(--body-borde); + max-width: 700px; + margin: -30px auto 40px; + position: relative; + z-index: 10; +} + +.contenedor_rosario h3 { + font-family: 'EB Garamond', serif; + font-size: 2rem; + color: var(--color-acento); + margin-bottom: 1rem; + text-align: center; + letter-spacing: 2px; +} + +.controles-rosario { + display: flex; + justify-content: space-between; + align-items: center; + margin: 20px 0; +} + +.btn-nav { + background-color: var(--color-primario); + color: white; + border: none; + padding: 10px 20px; + border-radius: 50px; + cursor: pointer; + font-weight: 600; + transition: all 0.3s ease; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); +} + +.btn-nav:hover { + background-color: var(--color-acento); + transform: translateY(-2px); +} + +.indicador-paso { + font-family: 'EB Garamond', serif; + font-weight: bold; + font-size: 1.2rem; + color: var(--body-texto); +} + +.imagen-misterio { + width: 100%; + border-radius: 15px; + transition: opacity 0.5s ease; + border: 5px solid var(--color-secundario); +} + +#lista-intenciones-index { + padding-left: 1.2rem; + margin: 0.5rem 0 0.8rem; +} + +#lista-intenciones-index li { + margin-bottom: 0.4rem; + line-height: 1.5; +} + +#lista-intenciones-index li.texto-suave { + list-style: none; + color: var(--color-texto-suave, #aaa); + font-style: italic; +} + +#imagen-misterio { + transition: opacity 0.4s ease-in-out; + display: block; + margin: 0 auto; + border: 4px solid var(--color-acento); /* Ese E8A23A en acción */ + border-radius: 15px; + max-width: 100%; + height: auto; +} + +.header-sesion { + position: absolute; + top: 0.6rem; + right: 1rem; + display: flex; + align-items: center; + gap: 0.6rem; + z-index: 100; +} + +.header-usuario { + color: white; + font-size: 0.85rem; + opacity: 0.9; +} + +.btn-cerrar-sesion { + padding: 0.3rem 0.8rem; + background: rgba(255,255,255,0.2); + color: white; + border: 1px solid rgba(255,255,255,0.5); + border-radius: 15px; + font-size: 0.8rem; + cursor: pointer; + transition: background 0.2s; + width: auto; + margin-top: 0; +} + +.btn-cerrar-sesion:hover { + background: rgba(255,255,255,0.35); +} + +.btn-sesion, +.btn-registro { + display: inline-block; + font-family: 'Nunito', sans-serif; + border-radius: 15px; + font-size: 0.8rem; + cursor: pointer; + text-decoration: none; + line-height: 1; + transition: background 0.2s, color 0.2s, border-color 0.2s; +} + +.btn-sesion { + padding: 0.3rem 0.8rem; + background: rgba(255,255,255,0.15); + color: white; + border: 1px solid rgba(255,255,255,0.4); +} + +.btn-sesion:hover { + background: rgba(255,255,255,0.3); +} + +.btn-registro { + padding: 0.3rem 0.9rem; + background: var(--color-acento); + color: var(--color-fondo); + border: 1px solid var(--color-acento); + font-weight: 700; +} + +.btn-registro:hover { + background: white; + color: var(--color-fondo); + border-color: white; +} + +body.modal-abierto { overflow: hidden; } + +.modal-auth-overlay { + display: none; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.7); + z-index: 9999; + align-items: center; + justify-content: center; + backdrop-filter: blur(3px); + padding: 1rem; +} + +.modal-auth-overlay.activo { + display: flex; + animation: modalFadeIn 0.2s ease; +} + +@keyframes modalFadeIn { + from { opacity: 0; transform: translateY(-12px); } + to { opacity: 1; transform: translateY(0); } +} + +.modal-auth-caja { + background: #0D1B2E; + border: 1px solid #2D4A7A; + border-radius: 14px; + padding: 2rem 2rem 1.6rem; + width: 100%; + max-width: 380px; + position: relative; + box-shadow: 0 20px 60px rgba(0,0,0,0.7); + color: #D8E4F5; +} + +.modal-auth-cerrar { + position: absolute; + top: 0.7rem; + right: 0.9rem; + background: none; + border: none; + color: #8BAAD4; + font-size: 1.5rem; + line-height: 1; + cursor: pointer; + padding: 0; + transition: color 0.2s; +} +.modal-auth-cerrar:hover { color: white; } + +.modal-auth-tabs { + display: flex; + gap: 0; + margin-bottom: 1.4rem; + border-bottom: 1px solid #2D4A7A; +} + +.modal-auth-tab { + flex: 1; + background: none; + border: none; + border-bottom: 2px solid transparent; + color: #8BAAD4; + font-family: 'Nunito', sans-serif; + font-size: 0.95rem; + font-weight: 600; + padding: 0.5rem 0; + cursor: pointer; + transition: color 0.2s, border-color 0.2s; + margin-bottom: -1px; +} + +.modal-auth-tab.activa { + color: #C9A84C; + border-bottom-color: #C9A84C; +} + +.modal-auth-tab:hover:not(.activa) { color: #D8E4F5; } + +.modal-auth-bienvenida { + font-family: 'EB Garamond', serif; + font-style: italic; + font-size: 1rem; + color: #8BAAD4; + margin: 0 0 1rem; + text-align: center; +} + +.modal-auth-panel input { + display: block; + width: 100%; + box-sizing: border-box; + background: #152540; + border: 1px solid #2D4A7A; + border-radius: 8px; + color: #D8E4F5; + font-family: 'Nunito', sans-serif; + font-size: 0.95rem; + padding: 0.6rem 0.85rem; + margin-bottom: 0.8rem; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.modal-auth-panel input:focus { + outline: none; + border-color: #C9A84C; + box-shadow: 0 0 0 2px rgba(201,168,76,0.2); +} + +.modal-auth-btn { + display: block; + width: 100%; + padding: 0.65rem; + background: #C9A84C; + color: #0D1B2E; + border: none; + border-radius: 8px; + font-family: 'Nunito', sans-serif; + font-size: 1rem; + font-weight: 700; + cursor: pointer; + margin-top: 0.3rem; + transition: background 0.2s, opacity 0.2s; +} + +.modal-auth-btn:hover:not(:disabled) { background: #e0bb5a; } +.modal-auth-btn:disabled { opacity: 0.6; cursor: default; } + +.modal-auth-msg { + min-height: 1.2rem; + text-align: center; + font-size: 0.88rem; + margin: 0.6rem 0 0; + border-radius: 6px; + padding: 0; +} + +.modal-auth-msg.error { color: #f08080; } +.modal-auth-msg.success { color: #7ec89c; } + +.modal-auth-pie { + text-align: center; + font-size: 0.8rem; + color: #8BAAD4; + margin: 0.8rem 0 0; +} +.modal-auth-pie a { color: #C9A84C; text-decoration: none; } +.modal-auth-pie a:hover { text-decoration: underline; } + +@media (max-width: 420px) { + .modal-auth-caja { padding: 1.5rem 1.2rem 1.2rem; } +} + diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css new file mode 100644 index 0000000..c5a4e4a --- /dev/null +++ b/src/main/resources/static/css/style.css @@ -0,0 +1,85 @@ +/* Oratio - Hoja de estilos principal */ + +:root { + --oratio-primary: #0054a4; + --oratio-dark: #003d73; + --oratio-light: #e6f0ff; +} + +/* Colores de marca */ +.bg-oratio { + background-color: var(--oratio-primary) !important; +} +.text-oratio { + color: var(--oratio-primary) !important; +} +.btn-oratio { + background-color: var(--oratio-primary); + border-color: var(--oratio-primary); + color: #fff; +} +.btn-oratio:hover { + background-color: var(--oratio-dark); + border-color: var(--oratio-dark); + color: #fff; +} +.btn-outline-oratio { + border-color: var(--oratio-primary); + color: var(--oratio-primary); +} +.btn-outline-oratio:hover { + background-color: var(--oratio-primary); + border-color: var(--oratio-primary); + color: #fff; +} + +/* Hero section */ +.hero-section { + background: linear-gradient(135deg, var(--oratio-primary) 0%, var(--oratio-dark) 100%); + min-height: 340px; + display: flex; + align-items: center; +} + +/* Feature icons */ +.feature-icon { + font-size: 2.5rem; +} + +/* Diario contenido - preservar saltos de línea */ +.diario-contenido { + white-space: pre-wrap; + font-size: 1.05rem; + line-height: 1.8; + color: #333; +} + +/* Navbar brand */ +.navbar-brand { + font-size: 1.3rem; + letter-spacing: 0.5px; +} + +/* Cards hover */ +.card { + transition: box-shadow 0.2s ease; +} +.card:hover { + box-shadow: 0 4px 16px rgba(107, 76, 138, 0.15) !important; +} + +/* Acceso rápido */ +a.card:hover { + transform: translateY(-2px); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +/* Nav tabs */ +.nav-tabs .nav-link.active { + color: var(--oratio-primary); + border-bottom-color: var(--oratio-primary); + font-weight: 600; +} +.nav-tabs .nav-link { + color: #666; +} diff --git a/src/main/resources/static/js/codigo.js b/src/main/resources/static/js/codigo.js new file mode 100644 index 0000000..af94ab5 --- /dev/null +++ b/src/main/resources/static/js/codigo.js @@ -0,0 +1,324 @@ + +// INICIALIZACIÓN DE LA PÁGINA +document.addEventListener("DOMContentLoaded", () => { + visualizarRosario(); + visualizarSalmo(); + visualizarLiturgia(); + visualizarSantoDelDia(); + recordatorioDifuntos(); + cargarIntencionesIndex(); + personalizarSeccionDiario(); +}); + + + +/* ============================================ + VARIABLES GLOBALES +============================================ */ + + +// Variables globales para elementos del DOM +let salmoDelDiaElem; +let fechaHoyElem, nombreCicloElem, cicloParImparElem, descripcionSantoDelDiaElem, indicadorLiturgicoElem, cabeceraHoy, menuPrincipalElem; + + + +/* ============================================ + INICIALIZAR VARIABLES +============================================ */ + + +function inicializarVariables() { + cabeceraHoy = document.getElementById('header-hoy'); + menuPrincipalElem = document.getElementById('menu-principal'); + salmoDelDiaElem = document.getElementById('salmo-pcpal'); + fechaHoyElem = document.getElementById('fecha-hoy'); + nombreCicloElem = document.getElementById('nombre_ciclo'); + cicloParImparElem = document.getElementById('ciclo_par_impar'); + descripcionSantoDelDiaElem = document.getElementById('descripcion-santo-del-dia'); + indicadorLiturgicoElem = document.getElementById('indicador-liturgico'); +} + + + +/* ============================================ + SALMO DEL DÍA +============================================ */ + + +async function visualizarSalmo() { + const salmoElem = document.getElementById('salmo-pcpal'); + if (!salmoElem) return; + try { + const res = await fetch('/data/salmos.json'); + const salmos = await res.json(); + const hoy = new Date(); + const diaAnyo = Math.floor((hoy - new Date(hoy.getFullYear(), 0, 0)) / 86400000); + const salmo = salmos[diaAnyo % salmos.length]; + if (salmo && salmo.texto) { + salmoElem.innerHTML = `${salmo.texto}
— Salmo ${salmo.numero}`; + } else { + salmoElem.textContent = "El Señor es mi pastor, nada me falta."; + } + } catch (e) { + salmoElem.textContent = "Bendice, alma mía, al Señor."; + } +} +// LITURGIA DEL DÍA DESDE calendario-liturgico.json +async function visualizarLiturgia() { + inicializarVariables(); + if (!fechaHoyElem || !nombreCicloElem || !cicloParImparElem || !indicadorLiturgicoElem) return; + const hoy = new Date(); + const fechaISO = hoy.toISOString().split('T')[0]; + fechaHoyElem.textContent = hoy.toLocaleDateString('es-ES', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); + cicloParImparElem.textContent = hoy.getFullYear() % 2 === 0 ? "Año Par" : "Año Impar"; + if (hoy.getFullYear() % 3 === 0) { + nombreCicloElem.textContent = "Ciclo C -"; + } else if (hoy.getFullYear() % 3 === 1) { + nombreCicloElem.textContent = "Ciclo A -"; + } else { + nombreCicloElem.textContent = "Ciclo B -"; + } + try { + const res = await fetch('/data/calendario-liturgico.json'); + const calendario = await res.json(); + const hoyLit = calendario.find(d => d.fecha === fechaISO); + if (hoyLit) { + const colorMap = { + "verde": "#2d5a27", + "morado": "#5d2d91", + "blanco": "#ffffff", + "rojo": "#b30000", + "azul": "#0074d9", + "rosa": "#e7b1cc", + "violeta": "#a0b5b0" + }; + const colorReal = colorMap[hoyLit.color] || "#333"; + if (cabeceraHoy) cabeceraHoy.style.backgroundColor = colorReal; + if (menuPrincipalElem) menuPrincipalElem.style.backgroundColor = colorReal; + indicadorLiturgicoElem.textContent = hoyLit.tiempo; + indicadorLiturgicoElem.style.color = (hoyLit.color === "blanco" || hoyLit.color === "rosa") ? "#2b2b2b" : "#fff"; + } + } catch (e) { + // fallback: no cambia nada + } +} +// SANTO DEL DÍA: si existe el elemento, lo deja como está (rellenado por Thymeleaf), si no, lo podría cargar de un endpoint o de un JSON en el futuro +function visualizarSantoDelDia() { + // Si quieres cargarlo por JS, aquí puedes hacerlo usando fetch a un endpoint o a un JSON + // Por defecto, Thymeleaf ya lo pone en el header +} + + + +/* ============================================ + ROSARIO DEL DÍA +============================================ */ + +function visualizarRosario() { + const MISTERIOS_DATA = { + 0: { nombre: "Gloriosos" }, + 1: { nombre: "Gozosos"}, + 2: { nombre: "Dolorosos" }, + 3: { nombre: "Gloriosos" }, + 4: { nombre: "Luminosos" }, + 5: { nombre: "Dolorosos" }, + 6: { nombre: "Gozosos" } + }; + + const hoy = new Date(); + const diaSemana = hoy.getDay(); + const misterioHoy = MISTERIOS_DATA[diaSemana]; + + const nombreMistElem = document.getElementById('nombre_misterio'); + if (nombreMistElem) { + nombreMistElem.textContent = `MISTERIOS ${misterioHoy.nombre.toUpperCase()}`; + } +} + + + +/* ============================================ + FECHA HUMANA +============================================ */ + +function visualizarDatos() { + const opcionesFecha = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; + const hoy = new Date(); + fechaHoyElem.textContent = hoy.toLocaleDateString('es-ES', opcionesFecha); +} + + + +/* ============================================ + CALENDARIO LITÚRGICO +============================================ */ + +/* ============================================ + RECORDATORIO DE DIFUNTOS +============================================ */ + +// RECORDATORIO DE DIFUNTOS: solo localStorage, sin API externa +function recordatorioDifuntos() { + const seccion = document.getElementById("seccion-recordatorio"); + if (!seccion) return; + const hoy = new Date(); + const mesActual = hoy.getMonth() + 1; + const mmdd = String(mesActual).padStart(2, "0") + "-" + String(hoy.getDate()).padStart(2, "0"); + const nombreMes = hoy.toLocaleDateString('es-ES', { month: 'long' }); + // Solo localStorage, sin usuario: clave fija + let todosDifuntos = JSON.parse(localStorage.getItem("difuntos_personales_anonimo") || "[]"); + if (todosDifuntos.length === 0) return; + const delMes = todosDifuntos.filter(d => { + const nacMes = d.nacimiento && !d.nacimiento.includes('XXXX') ? parseInt(d.nacimiento.split('-')[1]) : null; + const defMes = d.defuncion && !d.defuncion.includes('XXXX') ? parseInt(d.defuncion.split('-')[1]) : null; + return nacMes === mesActual || defMes === mesActual; + }); + if (delMes.length === 0) return; + const recordatorios = []; + delMes.forEach(d => { + if (d.nacimiento && !d.nacimiento.includes('XXXX')) { + const partes = d.nacimiento.split("-"); + if (partes.length === 3 && partes[1] + "-" + partes[2] === mmdd) { + const anios = hoy.getFullYear() - parseInt(partes[0]); + recordatorios.push("🎂 Hoy habría sido el cumpleaños de " + d.nombre + " — " + anios + " años"); + } + } + if (d.defuncion && !d.defuncion.includes('XXXX')) { + const partes = d.defuncion.split("-"); + if (partes.length === 3 && partes[1] + "-" + partes[2] === mmdd) { + const anios = hoy.getFullYear() - parseInt(partes[0]); + recordatorios.push("🕯 Hoy es el " + anios + ".º aniversario del fallecimiento de " + d.nombre + ""); + } + } + }); + seccion.style.display = "block"; + let html = `

🕯 En el recuerdo — ${nombreMes.charAt(0).toUpperCase() + nombreMes.slice(1)}

`; + if (recordatorios.length > 0) { + html += recordatorios.map(r => `

${r}

`).join(""); + html += '

"Dales, Señor, el descanso eterno y brille para ellos la luz perpetua."

'; + html += '
'; + } + html += '
    '; + delMes.forEach(d => { + let fechaStr = ""; + if (d.nacimiento && !d.nacimiento.includes('XXXX')) { + const dia = parseInt(d.nacimiento.split('-')[2]); + fechaStr += ` (🎂 ${dia})`; + } + if (d.defuncion && !d.defuncion.includes('XXXX')) { + const dia = parseInt(d.defuncion.split('-')[2]); + const anio = parseInt(d.defuncion.split('-')[0]); + fechaStr += ` (✝ ${dia}${anio > 1000 ? ' · ' + anio : ''})`; + } + html += '
  • 🕊 ' + d.nombre + fechaStr + '
  • '; + }); + html += '
'; + seccion.innerHTML = html; +} + + +/* ============================================ + CALENDARIO LITÚRGICO +============================================ */ + +async function cargarYActualizarTodo() { + const hoy = new Date(); + const fechaISO = hoy.toISOString().split('T')[0]; + + cicloParImparElem.textContent = hoy.getFullYear() % 2 === 0 ? "Año Par" : "Año Impar"; + + if (hoy.getFullYear() % 3 === 0) { + nombreCicloElem.textContent = "Ciclo C -"; + } else if (hoy.getFullYear() % 3 === 1) { + nombreCicloElem.textContent = "Ciclo A -"; + } else { + nombreCicloElem.textContent = "Ciclo B -"; + } + + try { + const respuesta = await fetch(`${API_BASE}/calendario/hoy`); + if (!respuesta.ok) throw new Error("Sin datos litúrgicos"); + const datosHoy = await respuesta.json(); + + const mapaColores = { + "verde": "#2d5a27", + "morado": "#5d2d91", + "blanco": "#ffffff", + "rojo": "#b30000", + "azul": "#0074d9", + "rosa": "#e7b1cc", + "violeta": "#a0b5b0" + }; + + if (datosHoy) { + const colorReal = mapaColores[datosHoy.color] || "#333"; + const colorTexto = (datosHoy.color === "blanco" || datosHoy.color === "rosa") ? "#2b2b2b" : "#ffffff"; + + cabeceraHoy.style.backgroundColor = colorReal; + menuPrincipalElem.style.backgroundColor = colorReal; + cabeceraHoy.style.color = colorTexto; + + indicadorLiturgicoElem.textContent = datosHoy.tiempo; + indicadorLiturgicoElem.style.color = colorTexto; + } + + } catch (error) { + console.error("Error cargando el calendario:", error); + } +} + + +/* ============================================ + INTENCIONES DEL USUARIO EN LA PORTADA +============================================ */ + + +function cargarIntencionesIndex() { + const lista = document.getElementById("lista-intenciones-index"); + if (!lista) return; + // Solo localStorage, sin usuario + const local = JSON.parse(localStorage.getItem("intenciones") || "[]"); + if (local.length === 0) { + lista.innerHTML = '
  • Aún no tienes intenciones. Añadir
  • '; + return; + } + lista.innerHTML = local.slice(0, 5).map(i => `
  • ${i.texto}
  • `).join(""); +} + + + +/* ============================================ + PERSONALIZACIÓN SECCIÓN DIARIO EN PORTADA +============================================ */ + + +function personalizarSeccionDiario() { + const previewElem = document.getElementById('diario-preview-index'); + const textoElem = document.getElementById('texto-diario-index'); + const botonElem = document.getElementById('boton-diario-index'); + if (!previewElem) return; + // Solo localStorage, sin usuario + const hoy = (() => { + const d = new Date(); + const offset = d.getTimezoneOffset() * 60000; + return new Date(d - offset).toISOString().split('T')[0]; + })(); + let entradas = {}; + try { + const data = localStorage.getItem(`diario_anonimo`); + if (data) entradas = JSON.parse(data); + } catch (e) { /* sin entradas */ } + const entradaHoy = entradas[hoy] || null; + if (entradaHoy && entradaHoy.texto) { + const icono = { paz: '🕊️', gratitud: '🙏', lucha: '😔', gozo: '✨', silencio: '🌿' }[entradaHoy.estado] || '🕯'; + const preview = entradaHoy.texto.substring(0, 120) + (entradaHoy.texto.length > 120 ? '…' : ''); + previewElem.innerHTML = ` +
    + ${icono} ${entradaHoy.titulo || 'Mi oración de hoy'} + ${preview} +
    + `; + if (botonElem) botonElem.textContent = 'Continuar escribiendo'; + } +} diff --git a/src/main/resources/templates/diario/lista.html b/src/main/resources/templates/diario/lista.html new file mode 100644 index 0000000..75d8e98 --- /dev/null +++ b/src/main/resources/templates/diario/lista.html @@ -0,0 +1,61 @@ + + + + + + + +
    +
    +
    +

    Mi Diario Espiritual

    + + Nueva entrada + +
    + +
    +
    📔
    +

    Tu diario está vacío. Comienza escribiendo tu primera reflexión.

    + Escribir primera entrada +
    + +
    +
    +
    +
    +
    + + +
    +
    +

    +
    + +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/diario/nueva.html b/src/main/resources/templates/diario/nueva.html new file mode 100644 index 0000000..b0e03e3 --- /dev/null +++ b/src/main/resources/templates/diario/nueva.html @@ -0,0 +1,72 @@ + + + + + + + +
    +
    +
    +
    +
    +
    +
    + + + Nueva entrada + +
    +
    +
    +
    + +
    + + +
    +
    + +
    + + +
    + +
    + + +
    +
    + +
    + + + Cancelar + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/diario/ver.html b/src/main/resources/templates/diario/ver.html new file mode 100644 index 0000000..39982e4 --- /dev/null +++ b/src/main/resources/templates/diario/ver.html @@ -0,0 +1,44 @@ + + + + + + + +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +

    +
    +
    +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/difuntos/lista.html b/src/main/resources/templates/difuntos/lista.html new file mode 100644 index 0000000..e27912d --- /dev/null +++ b/src/main/resources/templates/difuntos/lista.html @@ -0,0 +1,69 @@ + + + + + + + +
    +
    +
    +

    Rezo por mis difuntos

    + + Añadir + +
    + +
    +
    🕊️
    +

    No has añadido ningún difunto todavía.

    + Añadir difunto +
    + +
    +
    +
    +
    +
    🕊️
    +
    +

    +

    + + +

    +

    +
    + +
    +
    +
    + + +
    +
    +

    + "Concédeles, Señor, el descanso eterno,
    + y brille para ellos la luz perpetua.
    + Descansen en paz. Amén." +

    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/difuntos/nuevo.html b/src/main/resources/templates/difuntos/nuevo.html new file mode 100644 index 0000000..accda3d --- /dev/null +++ b/src/main/resources/templates/difuntos/nuevo.html @@ -0,0 +1,78 @@ + + + + + + + +
    +
    +
    +
    +
    +
    +
    + Añadir difunto +
    +
    +
    +
    + +
    + + +
    +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + + Cancelar + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/fragments/head.html b/src/main/resources/templates/fragments/head.html new file mode 100644 index 0000000..57aa2b7 --- /dev/null +++ b/src/main/resources/templates/fragments/head.html @@ -0,0 +1,10 @@ + + + + + + Oración + + + diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html new file mode 100644 index 0000000..08241c9 --- /dev/null +++ b/src/main/resources/templates/fragments/navbar.html @@ -0,0 +1,52 @@ + + + +
    +

    CAMINO DE ORACIÓN

    + +
    + Martes, 15 de enero de 2026 +
    + ABC + Par o impar +
    +
    + + Tiempo Ordinario +
    +
    + +
    +

    Santa Maria Madre de Dios

    +
    (Patrona de los conductores)
    +
    + +
    + + + Usuario + +
    + +
    +
    + + Entrar + Registrarse + +
    + + + + +
    + + diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html new file mode 100644 index 0000000..648ca3c --- /dev/null +++ b/src/main/resources/templates/home.html @@ -0,0 +1,69 @@ + + + + + + + +
    + + +
    +

    Salmo del día

    +

    +
    +
    + + +
    +

    🙏 Intención de hoy

    +
      +
    • Por la paz en el mundo y el fin de los conflictos.
    • +
    • Por los enfermos y sus familias, para que encuentren consuelo y sanación.
    • +
    • Por los líderes del mundo, para que gobiernen con sabiduría y justicia.
    • +
    + Intenciones de oración +
    + + +
    +

    🕯 Mi diario espiritual

    +

    + Un espacio personal para escribir lo que llevas en el corazón +

    +
    + Escribir en mi diario +
    + +
    +
    +

    Rosario

    +

    Misterios Gozosos

    + Rezar ahora +
    +
    + +
    +
    +

    Oraciones

    +

    Padre Nuestro, Ave María, Gloria

    + Ver Oraciones +
    +
    + +
    +
    +

    Biblioteca cristiana

    +

    Recomendaciones de libros y recursos cristianos

    + Ver Biblioteca +
    +
    +
    + +
    + Camino de Oración — Avanza en la fe +
    + + + + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..3ebb8c5 --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,86 @@ + + + + + Recursos Católicos + + + + + + + +
    + +
    + + +
    + + +
    +
    +
    + + +
    +

    🙏 Intención de hoy

    +
      +
    • Por la paz en el mundo y el fin de los conflictos.
    • +
    • Por los enfermos y sus familias, para que encuentren consuelo y sanación.
    • +
    • Por los líderes del mundo, para que gobiernen con sabiduría y justicia.
    • +
    + Intenciones de oración +
    + + +
    +

    🕯 Mi diario espiritual

    +

    + Un espacio personal para escribir lo que llevas en el corazón +

    +
    + Escribir en mi diario +
    + +
    +
    +

    Rosario

    +

    Misterios Gozosos

    + Rezar ahora +
    +
    + +
    +
    +

    Oraciones

    +

    Padre Nuestro, Ave María, Gloria

    + Ver Oraciones +
    +
    + +
    +
    +

    Biblioteca cristiana

    +

    Recomendaciones de libros y recursos cristianos

    + Ver Biblioteca +
    +
    + + + + +
    + + + + + + + diff --git a/src/main/resources/templates/inicio.html b/src/main/resources/templates/inicio.html new file mode 100644 index 0000000..186508c --- /dev/null +++ b/src/main/resources/templates/inicio.html @@ -0,0 +1,144 @@ + + + + + + + +
    +
    + + +

    + Bienvenido/a, Usuario 🙏 +

    + + +
    +
    +
    +
    +
    + Santo del día +
    +

    Santo del día

    +
    +
    +
    +
    +
    +
    +
    + Evangelio del día +
    +

    Fecha

    +

    + + Leer Evangelio + +
    +
    +
    +
    + + + + + +
    +
    +
    +
    + Intenciones comunitarias recientes +
    +
      +
    • + + + +
    • +
    +
    + No hay intenciones comunitarias todavía. +
    + +
    +
    +
    +
    +
    + Mis difuntos +
    +
      +
    • + + + +
    • +
    +
    + Aún no has añadido difuntos. +
    + +
    +
    +
    + +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..55e71d3 --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,60 @@ + + + + + + + +
    +
    +
    +
    +
    +

    + Iniciar sesión +

    + +
    + Cuenta creada correctamente. Ya puedes entrar. +
    +
    + Email o contraseña incorrectos. +
    +
    + Has cerrado sesión correctamente. +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + +
    +

    + ¿No tienes cuenta? + Regístrate +

    +
    +
    +
    +
    +
    + + + + diff --git a/src/main/resources/templates/oraciones/lista.html b/src/main/resources/templates/oraciones/lista.html new file mode 100644 index 0000000..821267e --- /dev/null +++ b/src/main/resources/templates/oraciones/lista.html @@ -0,0 +1,109 @@ + + + + + + + +
    +
    +
    +

    Peticiones de Oración

    + + Nueva petición + +
    + + + + +
    + +
    +
    +

    No tienes peticiones todavía.

    +
    +
    +
    +
    +
    +
    + Comunitaria + Privada + Respondida ✓ + +
    +
    +

    +
    + +
    +
    +
    +
    + + +
    +
    +

    No hay intenciones comunitarias todavía.

    +
    +
    +
    +
    +
    +
    + + +
    +
    +

    +
    + Respondida ✓ +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/oraciones/nueva.html b/src/main/resources/templates/oraciones/nueva.html new file mode 100644 index 0000000..8347e87 --- /dev/null +++ b/src/main/resources/templates/oraciones/nueva.html @@ -0,0 +1,83 @@ + + + + + + + +
    +
    +
    +
    +
    +
    +
    + Nueva petición de oración +
    +
    +
    +
    + +
    + + +
    +
    + +
    + + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + + + Cancelar + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Oratio — Ora et Labora +
    + + + + diff --git a/src/main/resources/templates/registro.html b/src/main/resources/templates/registro.html new file mode 100644 index 0000000..c6c6c53 --- /dev/null +++ b/src/main/resources/templates/registro.html @@ -0,0 +1,64 @@ + + + + + + + +
    +
    +
    +
    +
    +

    + Crear cuenta +

    + +
    + +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + +
    +
    + +
    +

    + ¿Ya tienes cuenta? Entrar +

    +
    +
    +
    +
    +
    + + + + diff --git a/src/test/java/es/tatvil/oracion/OracionApplicationTests.java b/src/test/java/es/tatvil/oracion/OracionApplicationTests.java new file mode 100644 index 0000000..bb4ae06 --- /dev/null +++ b/src/test/java/es/tatvil/oracion/OracionApplicationTests.java @@ -0,0 +1,13 @@ +package es.tatvil.oracion; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OracionApplicationTests { + + @Test + void contextLoads() { + } + +}