first commit
This commit is contained in:
commit
e37b1b2596
|
|
@ -0,0 +1,8 @@
|
|||
.gradle/
|
||||
build/
|
||||
.git/
|
||||
.gitignore
|
||||
*.md
|
||||
.idea/
|
||||
*.iml
|
||||
out/
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.jar binary
|
||||
|
|
@ -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/
|
||||
|
|
@ -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"]
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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:
|
||||
Binary file not shown.
|
|
@ -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
|
||||
|
|
@ -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" "$@"
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'oracion'
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Diario, Long> {
|
||||
List<Diario> findByUsuarioOrderByFechaDesc(Usuario usuario);
|
||||
Optional<Diario> findByIdAndUsuario(Long id, Usuario usuario);
|
||||
}
|
||||
|
|
@ -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<Diario> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Difunto, Long> {
|
||||
List<Difunto> findByUsuarioOrderByNombreAsc(Usuario usuario);
|
||||
Optional<Difunto> findByIdAndUsuario(Long id, Usuario usuario);
|
||||
}
|
||||
|
|
@ -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<Difunto> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Oracion, Long> {
|
||||
List<Oracion> findByUsuarioOrderByFechaCreacionDesc(Usuario usuario);
|
||||
List<Oracion> findByTipoOrderByFechaCreacionDesc(TipoOracion tipo);
|
||||
Optional<Oracion> findByIdAndUsuario(Long id, Usuario usuario);
|
||||
}
|
||||
|
|
@ -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<Oracion> listarPorUsuario(Usuario usuario) {
|
||||
return oracionRepository.findByUsuarioOrderByFechaCreacionDesc(usuario);
|
||||
}
|
||||
|
||||
public List<Oracion> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package es.tatvil.oracion.oracion;
|
||||
|
||||
public enum TipoOracion {
|
||||
PRIVADA, COMUNITARIA
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Para peticiones privadas/comunitarias
|
||||
|
|
@ -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<Salmo> SALMOS;
|
||||
static {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Salmo> salmosTmp = List.of();
|
||||
try {
|
||||
var resource = new ClassPathResource("data/salmos.json");
|
||||
if (resource.exists()) {
|
||||
salmosTmp = mapper.readValue(resource.getInputStream(), new TypeReference<List<Salmo>>(){});
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, SantoInfo> SANTOS = new HashMap<>();
|
||||
static {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
var resource = new ClassPathResource("data/santos.json");
|
||||
if (resource.exists()) {
|
||||
Map<String, SantoInfo> map = mapper.readValue(resource.getInputStream(), new TypeReference<Map<String, SantoInfo>>(){});
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<? extends GrantedAuthority> 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; }
|
||||
}
|
||||
|
|
@ -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<Usuario, Long> {
|
||||
Optional<Usuario> findByEmail(String email);
|
||||
boolean existsByEmail(String email);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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" }
|
||||
]
|
||||
|
||||
|
|
@ -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." }
|
||||
]
|
||||
|
|
@ -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." }
|
||||
]
|
||||
|
|
@ -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." }
|
||||
}
|
||||
|
|
@ -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');
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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}<br><cite style="font-size:0.8em;opacity:0.7;">— Salmo ${salmo.numero}</cite>`;
|
||||
} 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 <strong>" + d.nombre + "</strong> — " + 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 <strong>" + d.nombre + "</strong>");
|
||||
}
|
||||
}
|
||||
});
|
||||
seccion.style.display = "block";
|
||||
let html = `<h3>🕯 En el recuerdo — ${nombreMes.charAt(0).toUpperCase() + nombreMes.slice(1)}</h3>`;
|
||||
if (recordatorios.length > 0) {
|
||||
html += recordatorios.map(r => `<p>${r}</p>`).join("");
|
||||
html += '<p class="recordatorio-oracion"><em>"Dales, Señor, el descanso eterno y brille para ellos la luz perpetua."</em></p>';
|
||||
html += '<hr style="border-color:rgba(255,255,255,0.15);margin:0.8rem 0;">';
|
||||
}
|
||||
html += '<ul class="lista-difuntos-index">';
|
||||
delMes.forEach(d => {
|
||||
let fechaStr = "";
|
||||
if (d.nacimiento && !d.nacimiento.includes('XXXX')) {
|
||||
const dia = parseInt(d.nacimiento.split('-')[2]);
|
||||
fechaStr += ` <span class="anio-difunto">(🎂 ${dia})</span>`;
|
||||
}
|
||||
if (d.defuncion && !d.defuncion.includes('XXXX')) {
|
||||
const dia = parseInt(d.defuncion.split('-')[2]);
|
||||
const anio = parseInt(d.defuncion.split('-')[0]);
|
||||
fechaStr += ` <span class="anio-difunto">(✝ ${dia}${anio > 1000 ? ' · ' + anio : ''})</span>`;
|
||||
}
|
||||
html += '<li>🕊 ' + d.nombre + fechaStr + '</li>';
|
||||
});
|
||||
html += '</ul>';
|
||||
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 = '<li class="texto-suave">Aún no tienes intenciones. <a href="intenciones.html">Añadir</a></li>';
|
||||
return;
|
||||
}
|
||||
lista.innerHTML = local.slice(0, 5).map(i => `<li>${i.texto}</li>`).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 = `
|
||||
<div class="diario-preview-index">
|
||||
<strong>${icono} ${entradaHoy.titulo || 'Mi oración de hoy'}</strong>
|
||||
${preview}
|
||||
</div>
|
||||
`;
|
||||
if (botonElem) botonElem.textContent = 'Continuar escribiendo';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Mi Diario')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="mb-0"><i class="bi bi-journal-text text-oratio"></i> Mi Diario Espiritual</h4>
|
||||
<a th:href="@{/diario/nueva}" class="btn btn-oratio">
|
||||
<i class="bi bi-plus-lg"></i> Nueva entrada
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div th:if="${#lists.isEmpty(entradas)}" class="text-center text-muted py-5">
|
||||
<div class="fs-1 mb-3">📔</div>
|
||||
<p>Tu diario está vacío. Comienza escribiendo tu primera reflexión.</p>
|
||||
<a th:href="@{/diario/nueva}" class="btn btn-oratio">Escribir primera entrada</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3" th:unless="${#lists.isEmpty(entradas)}">
|
||||
<div class="col-md-6 col-lg-4" th:each="e : ${entradas}">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<div class="text-muted small mb-1">
|
||||
<i class="bi bi-calendar3"></i>
|
||||
<span th:text="${#temporals.format(e.fecha, 'd MMM yyyy')}"></span>
|
||||
</div>
|
||||
<h6 class="card-title" th:text="${e.titulo}"></h6>
|
||||
<p class="card-text text-muted small"
|
||||
th:text="${#strings.abbreviate(e.contenido, 100)}"></p>
|
||||
</div>
|
||||
<div class="card-footer bg-white border-0 d-flex gap-2">
|
||||
<a th:href="@{/diario/{id}(id=${e.id})}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-eye"></i> Ver
|
||||
</a>
|
||||
<a th:href="@{/diario/{id}/editar(id=${e.id})}" class="btn btn-sm btn-outline-oratio">
|
||||
<i class="bi bi-pencil"></i> Editar
|
||||
</a>
|
||||
<form th:action="@{/diario/{id}/eliminar(id=${e.id})}" method="post"
|
||||
onsubmit="return confirm('¿Eliminar esta entrada?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Entrada de Diario')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-pencil-square text-oratio"></i>
|
||||
<span th:text="${entrada.id == null} ? 'Nueva entrada' : 'Editar entrada'">
|
||||
Nueva entrada
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form th:action="${entrada.id == null} ? @{/diario/nueva} : @{/diario/{id}/editar(id=${entrada.id})}"
|
||||
th:object="${entrada}" method="post">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="titulo" class="form-label fw-semibold">Título</label>
|
||||
<input type="text" id="titulo" th:field="*{titulo}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('titulo')} ? 'is-invalid'"
|
||||
required placeholder="¿De qué quieres escribir hoy?"/>
|
||||
<div class="invalid-feedback" th:errors="*{titulo}"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="fecha" class="form-label fw-semibold">Fecha</label>
|
||||
<input type="date" id="fecha" th:field="*{fecha}"
|
||||
class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="contenido" class="form-label fw-semibold">Reflexión</label>
|
||||
<textarea id="contenido" th:field="*{contenido}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('contenido')} ? 'is-invalid'"
|
||||
rows="10" required
|
||||
placeholder="Escribe tu reflexión, oración o agradecimiento..."></textarea>
|
||||
<div class="invalid-feedback" th:errors="*{contenido}"></div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-oratio">
|
||||
<i class="bi bi-save"></i> Guardar
|
||||
</button>
|
||||
<a th:href="@{/diario}" class="btn btn-outline-secondary">
|
||||
Cancelar
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Diario')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
||||
<div class="text-muted small">
|
||||
<i class="bi bi-calendar3"></i>
|
||||
<span th:text="${#temporals.format(entrada.fecha, 'd MMMM yyyy')}"></span>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a th:href="@{/diario/{id}/editar(id=${entrada.id})}"
|
||||
class="btn btn-sm btn-outline-oratio">
|
||||
<i class="bi bi-pencil"></i> Editar
|
||||
</a>
|
||||
<a th:href="@{/diario}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Volver
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<h4 class="mb-4" th:text="${entrada.titulo}"></h4>
|
||||
<div class="diario-contenido" th:text="${entrada.contenido}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Mis Difuntos')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="mb-0"><i class="bi bi-flower1 text-oratio"></i> Rezo por mis difuntos</h4>
|
||||
<a th:href="@{/difuntos/nuevo}" class="btn btn-oratio">
|
||||
<i class="bi bi-plus-lg"></i> Añadir
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div th:if="${#lists.isEmpty(difuntos)}" class="text-center text-muted py-5">
|
||||
<div class="fs-1 mb-3">🕊️</div>
|
||||
<p>No has añadido ningún difunto todavía.</p>
|
||||
<a th:href="@{/difuntos/nuevo}" class="btn btn-oratio">Añadir difunto</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3" th:unless="${#lists.isEmpty(difuntos)}">
|
||||
<div class="col-md-4 col-lg-3" th:each="d : ${difuntos}">
|
||||
<div class="card border-0 shadow-sm h-100 text-center">
|
||||
<div class="card-body py-4">
|
||||
<div class="fs-2 mb-2">🕊️</div>
|
||||
<h6 class="card-title mb-1" th:text="${d.nombre}"></h6>
|
||||
<p class="text-muted small mb-1" th:if="${d.relacion}"
|
||||
th:text="${d.relacion}"></p>
|
||||
<p class="text-muted small" th:if="${d.fechaFallecimiento}">
|
||||
<i class="bi bi-calendar3"></i>
|
||||
<span th:text="${#temporals.format(d.fechaFallecimiento, 'd MMM yyyy')}"></span>
|
||||
</p>
|
||||
<p class="text-muted small fst-italic" th:if="${d.notas}"
|
||||
th:text="${d.notas}"></p>
|
||||
</div>
|
||||
<div class="card-footer bg-white border-0">
|
||||
<form th:action="@{/difuntos/{id}/eliminar(id=${d.id})}" method="post"
|
||||
onsubmit="return confirm('¿Eliminar a ' + '[[${d.nombre}]]' + '?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i> Eliminar
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Oración por los difuntos -->
|
||||
<div class="card border-0 shadow-sm mt-5">
|
||||
<div class="card-body p-4 text-center">
|
||||
<p class="fst-italic text-muted mb-0">
|
||||
"Concédeles, Señor, el descanso eterno,<br/>
|
||||
y brille para ellos la luz perpetua.<br/>
|
||||
Descansen en paz. Amén."
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Añadir Difunto')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-flower1 text-oratio"></i> Añadir difunto
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form th:action="@{/difuntos/nuevo}" th:object="${difunto}" method="post">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="nombre" class="form-label fw-semibold">Nombre</label>
|
||||
<input type="text" id="nombre" th:field="*{nombre}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('nombre')} ? 'is-invalid'"
|
||||
required placeholder="Nombre completo"/>
|
||||
<div class="invalid-feedback" th:errors="*{nombre}"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="relacion" class="form-label fw-semibold">
|
||||
Relación <span class="text-muted fw-normal">(opcional)</span>
|
||||
</label>
|
||||
<input type="text" id="relacion" th:field="*{relacion}"
|
||||
class="form-control"
|
||||
placeholder="Ej: Padre, Abuela, Amigo..."/>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="fechaFallecimiento" class="form-label fw-semibold">
|
||||
Fecha de fallecimiento <span class="text-muted fw-normal">(opcional)</span>
|
||||
</label>
|
||||
<input type="date" id="fechaFallecimiento"
|
||||
th:field="*{fechaFallecimiento}" class="form-control"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="notas" class="form-label fw-semibold">
|
||||
Notas <span class="text-muted fw-normal">(opcional)</span>
|
||||
</label>
|
||||
<textarea id="notas" th:field="*{notas}"
|
||||
class="form-control" rows="3"
|
||||
placeholder="Recuerdos, intenciones..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-oratio">
|
||||
<i class="bi bi-save"></i> Guardar
|
||||
</button>
|
||||
<a th:href="@{/difuntos}" class="btn btn-outline-secondary">
|
||||
Cancelar
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head th:fragment="head(titulo)">
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title th:text="${titulo} + ' | Oración'">Oración</title>
|
||||
<link rel="stylesheet" th:href="@{/css/estilos.css}"/>
|
||||
</head>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<body>
|
||||
<header th:fragment="navbar" class="header-hoy" id="header-hoy">
|
||||
<h1 class="titulo">CAMINO DE ORACIÓN</h1>
|
||||
|
||||
<div class="fecha">
|
||||
<span id="fecha-hoy" th:text="${fechaHoy}">Martes, 15 de enero de 2026</span>
|
||||
<div class="ciclo">
|
||||
<span id="nombre_ciclo" th:text="${nombreCiclo}">ABC</span>
|
||||
<span id="ciclo_par_impar" th:text="${cicloParImpar}">Par o impar</span>
|
||||
</div>
|
||||
<div id="indicador-liturgico" class="liturgico">
|
||||
<span class="color-dia" id="color-liturgico" th:style="'background:' + ${colorLiturgico}" th:title="${nombreLiturgico}"></span>
|
||||
<span class="nombre-color" id="tiempo-liturgico" th:text="${nombreLiturgico}">Tiempo Ordinario</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="santo">
|
||||
<h2 id="santo-del-dia" th:text="${santo.nombre}">Santa Maria Madre de Dios</h2>
|
||||
<div id="descripcion-santo-del-dia" th:text="${santo.descripcion}">(Patrona de los conductores)</div>
|
||||
</div>
|
||||
|
||||
<div id="header-sesion" class="header-sesion">
|
||||
<span sec:authorize="isAuthenticated()">
|
||||
<span class="header-usuario">
|
||||
<span sec:authentication="principal.nombre">Usuario</span>
|
||||
</span>
|
||||
<form th:action="@{/logout}" method="post" style="display:inline;">
|
||||
<button type="submit" class="btn-cerrar-sesion">Salir</button>
|
||||
</form>
|
||||
</span>
|
||||
<span sec:authorize="!isAuthenticated()">
|
||||
<a class="btn-sesion" th:href="@{/login}">Entrar</a>
|
||||
<a class="btn-registro" th:href="@{/registro}">Registrarse</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button class="menu-toggle" id="menu-toggle">☰</button>
|
||||
|
||||
<nav class="menu-principal" id="menu-principal">
|
||||
<a th:href="@{/}" >Inicio</a>
|
||||
<a th:href="@{/rosario}">Rosario</a>
|
||||
<a th:href="@{/oraciones}">Oraciones Básicas</a>
|
||||
<a th:href="@{/intenciones}">Intenciones</a>
|
||||
<a th:href="@{/diario}">Diario</a>
|
||||
<a th:href="@{/biblioteca}">Biblioteca cristiana</a>
|
||||
</nav>
|
||||
</header>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head th:replace="~{fragments/head :: head('Inicio')}"></head>
|
||||
<body>
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="contenedor">
|
||||
|
||||
<!-- SALMO DEL DÍA (dinámico) -->
|
||||
<section class="bloque">
|
||||
<h3>Salmo del día</h3>
|
||||
<p><b th:text="'Salmo ' + ${salmo.numero}"></b></p>
|
||||
<blockquote class="salmo" th:text="${salmo.texto}"></blockquote>
|
||||
</section>
|
||||
|
||||
<!-- INTENCIÓN -->
|
||||
<section class="bloque" id="seccion-intenciones">
|
||||
<h3 id="titulo-intenciones">🙏 Intención de hoy</h3>
|
||||
<ul id="lista-intenciones-index">
|
||||
<li>Por la paz en el mundo y el fin de los conflictos.</li>
|
||||
<li>Por los enfermos y sus familias, para que encuentren consuelo y sanación.</li>
|
||||
<li>Por los líderes del mundo, para que gobiernen con sabiduría y justicia.</li>
|
||||
</ul>
|
||||
<a href="#" class="boton">Intenciones de oración</a>
|
||||
</section>
|
||||
|
||||
<!-- DIARIO -->
|
||||
<section class="bloque bloque-intimo" id="seccion-diario-index">
|
||||
<h3>🕯 Mi diario espiritual</h3>
|
||||
<p class="texto-suave" id="texto-diario-index">
|
||||
Un espacio personal para escribir lo que llevas en el corazón
|
||||
</p>
|
||||
<div id="diario-preview-index"></div>
|
||||
<a href="#" class="boton" id="boton-diario-index">Escribir en mi diario</a>
|
||||
</section>
|
||||
|
||||
<section class="bloque-fondo" style="background-image: url('/img/rosario.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Rosario</h3>
|
||||
<p id="nombre_misterio">Misterios Gozosos</p>
|
||||
<a href="#" class="boton">Rezar ahora</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bloque-fondo" style="background-image: url('/img/oraciones.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Oraciones</h3>
|
||||
<p>Padre Nuestro, Ave María, Gloria</p>
|
||||
<a href="#" class="boton">Ver Oraciones</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bloque-fondo" style="background-image: url('/img/biblioteca.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Biblioteca cristiana</h3>
|
||||
<p>Recomendaciones de libros y recursos cristianos</p>
|
||||
<a href="#" class="boton">Ver Biblioteca</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Camino de Oración — Avanza en la fe</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Recursos Católicos</title>
|
||||
<link rel="icon" type="image/x-icon" href="img/favicon.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="css/diario.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="header-container"></div>
|
||||
|
||||
<main class="contenedor">
|
||||
|
||||
<!-- RECORDATORIO DE DIFUNTOS (aparece solo cuando coincide un aniversario) -->
|
||||
<section id="seccion-recordatorio" class="bloque difuntos"></section>
|
||||
|
||||
<!-- SALMO -->
|
||||
<section class="bloque">
|
||||
<blockquote class="salmo" id="salmo-pcpal"></blockquote>
|
||||
</section>
|
||||
|
||||
<!-- INTENCIÓN -->
|
||||
<section class="bloque" id="seccion-intenciones">
|
||||
<h3 id="titulo-intenciones">🙏 Intención de hoy</h3>
|
||||
<ul id="lista-intenciones-index">
|
||||
<li>Por la paz en el mundo y el fin de los conflictos.</li>
|
||||
<li>Por los enfermos y sus familias, para que encuentren consuelo y sanación.</li>
|
||||
<li>Por los líderes del mundo, para que gobiernen con sabiduría y justicia.</li>
|
||||
</ul>
|
||||
<a href="intenciones.html" class="boton">Intenciones de oración</a>
|
||||
</section>
|
||||
|
||||
<!-- DIARIO -->
|
||||
<section class="bloque bloque-intimo" id="seccion-diario-index">
|
||||
<h3>🕯 Mi diario espiritual</h3>
|
||||
<p class="texto-suave" id="texto-diario-index">
|
||||
Un espacio personal para escribir lo que llevas en el corazón
|
||||
</p>
|
||||
<div id="diario-preview-index"></div>
|
||||
<a href="diario-oracion.html" class="boton" id="boton-diario-index">Escribir en mi diario</a>
|
||||
</section>
|
||||
|
||||
<section class="bloque bloque-fondo" style="background-image: url('img/rosario.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Rosario</h3>
|
||||
<p id="nombre_misterio">Misterios Gozosos</p>
|
||||
<a href="rosario.html" class="boton">Rezar ahora</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bloque bloque-fondo" style="background-image: url('img/oraciones.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Oraciones</h3>
|
||||
<p>Padre Nuestro, Ave María, Gloria</p>
|
||||
<a href="oraciones-basicas.html" class="boton">Ver Oraciones</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bloque bloque-fondo" style="background-image: url('img/biblioteca.jpg');">
|
||||
<div class="capa-oscura">
|
||||
<h3>Biblioteca cristiana</h3>
|
||||
<p>Recomendaciones de libros y recursos cristianos</p>
|
||||
<a href="biblioteca-cristiana.html" class="boton">Ver Biblioteca</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- RECURSOS -->
|
||||
<!--
|
||||
<section class="recursos">
|
||||
<a href="santos.html">Santos y novenas</a>
|
||||
<a href="calendario-liturgico/index.php">Calendario litúrgico</a>
|
||||
<a href="biblioteca-basica-cristiana.html">Biblioteca</a>
|
||||
</section>
|
||||
-->
|
||||
|
||||
</main>
|
||||
|
||||
<script src="js/api-config.js"></script>
|
||||
<script src="js/auth.js"></script>
|
||||
<script src="js/header.js"></script>
|
||||
<script src="js/codigo.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head th:replace="~{fragments/head :: head('Inicio')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
|
||||
<!-- Saludo -->
|
||||
<h4 class="mb-4 text-muted fw-normal">
|
||||
Bienvenido/a, <strong sec:authentication="principal.nombre">Usuario</strong> 🙏
|
||||
</h4>
|
||||
|
||||
<!-- Santo del día + Evangelio -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-oratio">
|
||||
<i class="bi bi-brightness-high"></i> Santo del día
|
||||
</h5>
|
||||
<p class="card-text fs-5" th:text="${santo}">Santo del día</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-oratio">
|
||||
<i class="bi bi-book-open"></i> Evangelio del día
|
||||
</h5>
|
||||
<p class="card-text fw-semibold" th:text="${evangelio.titulo()}">Fecha</p>
|
||||
<p class="card-text text-muted" th:text="${evangelio.texto()}"></p>
|
||||
<a th:href="${evangelio.enlace()}" target="_blank"
|
||||
class="btn btn-sm btn-outline-oratio">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Leer Evangelio
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Accesos rápidos -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6 col-md-3">
|
||||
<a th:href="@{/diario}" class="card text-decoration-none text-dark border-0 shadow-sm h-100">
|
||||
<div class="card-body text-center py-4">
|
||||
<div class="fs-2 mb-2">📔</div>
|
||||
<div class="fw-semibold">Mi Diario</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<a th:href="@{/oraciones}" class="card text-decoration-none text-dark border-0 shadow-sm h-100">
|
||||
<div class="card-body text-center py-4">
|
||||
<div class="fs-2 mb-2">🙏</div>
|
||||
<div class="fw-semibold">Oraciones</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<a th:href="@{/difuntos}" class="card text-decoration-none text-dark border-0 shadow-sm h-100">
|
||||
<div class="card-body text-center py-4">
|
||||
<div class="fs-2 mb-2">🕊️</div>
|
||||
<div class="fw-semibold">Difuntos</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<a th:href="@{/diario/nueva}" class="card text-decoration-none text-dark border-0 shadow-sm h-100">
|
||||
<div class="card-body text-center py-4">
|
||||
<div class="fs-2 mb-2">✍️</div>
|
||||
<div class="fw-semibold">Nueva entrada</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Intenciones comunitarias + Mis difuntos -->
|
||||
<div class="row g-4">
|
||||
<div class="col-md-7">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white fw-semibold">
|
||||
<i class="bi bi-people text-oratio"></i> Intenciones comunitarias recientes
|
||||
</div>
|
||||
<ul class="list-group list-group-flush"
|
||||
th:if="${not #lists.isEmpty(peticionesComunitarias)}">
|
||||
<li class="list-group-item" th:each="p : ${peticionesComunitarias}">
|
||||
<i class="bi bi-hands text-oratio me-2"></i>
|
||||
<span th:text="${p.titulo}"></span>
|
||||
<small class="text-muted ms-2" th:text="'— ' + ${p.usuario.nombre}"></small>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card-body text-muted text-center py-3"
|
||||
th:if="${#lists.isEmpty(peticionesComunitarias)}">
|
||||
No hay intenciones comunitarias todavía.
|
||||
</div>
|
||||
<div class="card-footer bg-white">
|
||||
<a th:href="@{/oraciones}" class="btn btn-sm btn-outline-oratio">
|
||||
Ver todas →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white fw-semibold">
|
||||
<i class="bi bi-flower1 text-oratio"></i> Mis difuntos
|
||||
</div>
|
||||
<ul class="list-group list-group-flush"
|
||||
th:if="${not #lists.isEmpty(misDifuntos)}">
|
||||
<li class="list-group-item" th:each="d : ${misDifuntos}">
|
||||
<i class="bi bi-person-heart text-oratio me-1"></i>
|
||||
<span th:text="${d.nombre}"></span>
|
||||
<small class="text-muted" th:if="${d.relacion}"
|
||||
th:text="' (' + ${d.relacion} + ')'"></small>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card-body text-muted text-center py-3"
|
||||
th:if="${#lists.isEmpty(misDifuntos)}">
|
||||
Aún no has añadido difuntos.
|
||||
</div>
|
||||
<div class="card-footer bg-white">
|
||||
<a th:href="@{/difuntos/nuevo}" class="btn btn-sm btn-outline-oratio">
|
||||
Añadir →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Entrar')}"></head>
|
||||
<body class="bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-4">
|
||||
<h4 class="card-title text-center mb-4">
|
||||
<i class="bi bi-person-circle text-oratio"></i> Iniciar sesión
|
||||
</h4>
|
||||
|
||||
<div th:if="${param.registrado}" class="alert alert-success">
|
||||
Cuenta creada correctamente. Ya puedes entrar.
|
||||
</div>
|
||||
<div th:if="${param.error}" class="alert alert-danger">
|
||||
Email o contraseña incorrectos.
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-info">
|
||||
Has cerrado sesión correctamente.
|
||||
</div>
|
||||
|
||||
<form th:action="@{/login}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" id="email" name="email"
|
||||
class="form-control" required autofocus
|
||||
placeholder="tu@email.com"/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Contraseña</label>
|
||||
<input type="password" id="password" name="password"
|
||||
class="form-control" required
|
||||
placeholder="••••••••"/>
|
||||
</div>
|
||||
<div class="d-grid mt-4">
|
||||
<button type="submit" class="btn btn-oratio">
|
||||
<i class="bi bi-box-arrow-in-right"></i> Entrar
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
<p class="text-center text-muted mb-0">
|
||||
¿No tienes cuenta?
|
||||
<a th:href="@{/registro}">Regístrate</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Peticiones de Oración')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="mb-0"><i class="bi bi-hands text-oratio"></i> Peticiones de Oración</h4>
|
||||
<a th:href="@{/oraciones/nueva}" class="btn btn-oratio">
|
||||
<i class="bi bi-plus-lg"></i> Nueva petición
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<ul class="nav nav-tabs mb-4" id="oracionTab">
|
||||
<li class="nav-item">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#mis-oraciones">
|
||||
<i class="bi bi-lock"></i> Mis peticiones
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#comunitarias">
|
||||
<i class="bi bi-people"></i> Comunitarias
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<!-- Mis peticiones -->
|
||||
<div class="tab-pane fade show active" id="mis-oraciones">
|
||||
<div th:if="${#lists.isEmpty(misOraciones)}" class="text-center text-muted py-4">
|
||||
<p>No tienes peticiones todavía.</p>
|
||||
</div>
|
||||
<div class="row g-3" th:unless="${#lists.isEmpty(misOraciones)}">
|
||||
<div class="col-md-6" th:each="o : ${misOraciones}">
|
||||
<div class="card border-0 shadow-sm h-100"
|
||||
th:classappend="${o.respondida} ? 'opacity-75'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<span th:if="${o.tipo.name() == 'COMUNITARIA'}"
|
||||
class="badge bg-info text-dark">Comunitaria</span>
|
||||
<span th:if="${o.tipo.name() == 'PRIVADA'}"
|
||||
class="badge bg-secondary">Privada</span>
|
||||
<span th:if="${o.respondida}" class="badge bg-success">Respondida ✓</span>
|
||||
<small class="text-muted"
|
||||
th:text="${#temporals.format(o.fechaCreacion, 'd MMM yyyy')}"></small>
|
||||
</div>
|
||||
<h6 class="card-title" th:text="${o.titulo}"></h6>
|
||||
<p class="card-text text-muted small" th:text="${o.descripcion}"></p>
|
||||
</div>
|
||||
<div class="card-footer bg-white border-0 d-flex gap-2"
|
||||
th:unless="${o.respondida}">
|
||||
<form th:action="@{/oraciones/{id}/respondida(id=${o.id})}" method="post">
|
||||
<button type="submit" class="btn btn-sm btn-outline-success">
|
||||
<i class="bi bi-check-circle"></i> Respondida
|
||||
</button>
|
||||
</form>
|
||||
<form th:action="@{/oraciones/{id}/eliminar(id=${o.id})}" method="post"
|
||||
onsubmit="return confirm('¿Eliminar esta petición?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Comunitarias -->
|
||||
<div class="tab-pane fade" id="comunitarias">
|
||||
<div th:if="${#lists.isEmpty(comunitarias)}" class="text-center text-muted py-4">
|
||||
<p>No hay intenciones comunitarias todavía.</p>
|
||||
</div>
|
||||
<div class="row g-3" th:unless="${#lists.isEmpty(comunitarias)}">
|
||||
<div class="col-md-6" th:each="o : ${comunitarias}">
|
||||
<div class="card border-0 shadow-sm h-100"
|
||||
th:classappend="${o.respondida} ? 'opacity-75'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<small class="text-muted fw-semibold"
|
||||
th:text="${o.usuario.nombre}"></small>
|
||||
<small class="text-muted"
|
||||
th:text="${#temporals.format(o.fechaCreacion, 'd MMM yyyy')}"></small>
|
||||
</div>
|
||||
<h6 class="card-title" th:text="${o.titulo}"></h6>
|
||||
<p class="card-text text-muted small" th:text="${o.descripcion}"></p>
|
||||
<div th:if="${o.respondida}">
|
||||
<span class="badge bg-success">Respondida ✓</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Nueva Petición')}"></head>
|
||||
<body class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-7">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-hands text-oratio"></i> Nueva petición de oración
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form th:action="@{/oraciones/nueva}" th:object="${oracion}" method="post">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="titulo" class="form-label fw-semibold">Título</label>
|
||||
<input type="text" id="titulo" th:field="*{titulo}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('titulo')} ? 'is-invalid'"
|
||||
required placeholder="Ej: Por la salud de mi madre"/>
|
||||
<div class="invalid-feedback" th:errors="*{titulo}"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="descripcion" class="form-label fw-semibold">
|
||||
Descripción <span class="text-muted fw-normal">(opcional)</span>
|
||||
</label>
|
||||
<textarea id="descripcion" th:field="*{descripcion}"
|
||||
class="form-control" rows="4"
|
||||
placeholder="Más detalles sobre la intención..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-semibold">Visibilidad</label>
|
||||
<div class="d-flex gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
id="tipoPrivada" th:field="*{tipo}" value="PRIVADA"/>
|
||||
<label class="form-check-label" for="tipoPrivada">
|
||||
<i class="bi bi-lock text-secondary"></i> Privada (solo yo)
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
id="tipoComunitaria" th:field="*{tipo}" value="COMUNITARIA"/>
|
||||
<label class="form-check-label" for="tipoComunitaria">
|
||||
<i class="bi bi-people text-info"></i> Comunitaria (todos rezan)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div th:if="${#fields.hasErrors('tipo')}"
|
||||
class="text-danger small" th:errors="*{tipo}"></div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-oratio">
|
||||
<i class="bi bi-save"></i> Guardar
|
||||
</button>
|
||||
<a th:href="@{/oraciones}" class="btn btn-outline-secondary">
|
||||
Cancelar
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-dark text-white-50 text-center py-3 mt-auto">
|
||||
<small>Oratio — Ora et Labora</small>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/head :: head('Registro')}"></head>
|
||||
<body class="bg-light">
|
||||
|
||||
<nav th:replace="~{fragments/navbar :: navbar}"></nav>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-4">
|
||||
<h4 class="card-title text-center mb-4">
|
||||
<i class="bi bi-person-plus text-oratio"></i> Crear cuenta
|
||||
</h4>
|
||||
|
||||
<div th:if="${errorEmail}" class="alert alert-danger"
|
||||
th:text="${errorEmail}"></div>
|
||||
|
||||
<form th:action="@{/registro}" th:object="${usuario}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="nombre" class="form-label">Nombre</label>
|
||||
<input type="text" id="nombre" th:field="*{nombre}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('nombre')} ? 'is-invalid'"
|
||||
required placeholder="Tu nombre"/>
|
||||
<div class="invalid-feedback" th:errors="*{nombre}"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" id="email" th:field="*{email}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('email')} ? 'is-invalid'"
|
||||
required placeholder="tu@email.com"/>
|
||||
<div class="invalid-feedback" th:errors="*{email}"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Contraseña</label>
|
||||
<input type="password" id="password" th:field="*{password}"
|
||||
class="form-control"
|
||||
th:classappend="${#fields.hasErrors('password')} ? 'is-invalid'"
|
||||
required placeholder="••••••••"/>
|
||||
<div class="invalid-feedback" th:errors="*{password}"></div>
|
||||
</div>
|
||||
<div class="d-grid mt-4">
|
||||
<button type="submit" class="btn btn-oratio">
|
||||
<i class="bi bi-check-circle"></i> Registrarme
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
<p class="text-center text-muted mb-0">
|
||||
¿Ya tienes cuenta? <a th:href="@{/login}">Entrar</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue