Compare commits
No commits in common. "main" and "status-postulacion" have entirely different histories.
main
...
status-pos
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Archivo de variables de entorno para la configuración de Google Sheets
|
||||||
|
GOOGLE_SERVICE_ACCOUNT_EMAIL=dbsheets@dbsheets-487314.iam.gserviceaccount.com
|
||||||
|
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCi2DVTbgH5WzE4\nrsT4BLcjplwszwkiZmhUxcVma/xI/6G+LQpzWTmmETmPWGFBpPukcoEDJDIugSFF\nuiKM+cSJIJJTYYWb5sBGXC6bi36AiA3W/zuRYGoFdNP+34iqepWpXpjKY8T0bbJJ\njhIgjW/SN2fYZeVBZqLATEzRqCcPYXI5gs9fyb2bzTEjiB3kCklVCudl/JDoxAWm\nJ9vO/OOXEgt/t97v9cMoo9OZ4Y3txqiQB41UdS97btDvpezc59u+8K9s5FT+yljC\nMyfRiRM+4MpycCoJobiT8NnCaNblMTd8mkfuujrFvnT/k9O794gBOJ2sgF7AYej4\nzm9tXpknAgMBAAECggEAM50bqcngTkydGT4rqAC2m1ILPRiR6JlU0CmvG3t2hxyf\nA0v7V/wbzYsAF3MHwGquZ7zzLy+1yA+doCAS+2Pe6yeruUnbs0I8BxEIpLxd6Bc3\na8GR+833TKtu1gW7p20bKoeVHfDpaB+stquVC0RJAPQWsfv54fTJ+PE2F+2YE8Np\njhWvM4OkUNZVBPZxG+RF0gzylIx2tw3QpLN3DMSr9Z2wGfohp7yryP96qqC1RFGQ\nCsaHsPRfzv+UNinGmA0Yzv79Stuqgsg+J3V/01Pm4ANutHix/kP0YAYCyg29UtVZ\nIJZtPOAfHWICYw+hQMpcfSLWzbkUQpwTTG0Bk6xmwQKBgQDUNf226UzdAm/V2Pag\nc1YF4P6Bru1A5jiFTpyrAYPSN+Wk84Gkl8XtuDDb7zXL+MaVb8aIVXTKhM2b0RDw\nHtDayoCCXci8VfP4sDRzjEGB1O1OPOl/wPD6L94CmNB0QeepNs4Q5xD0HEsoNN6s\nZGafIkIbVVUBCkuZwNxoLVXSKQKBgQDEcnKkgE/ror9vXSj0XY9Rn0wU2W6DreUt\nMizWyH9R0wBbaSJQ/4Wd3F6co2H2DSuZgXxLJvsPlqffUivs/oZnlx8HhWi6vjLL\nvSiqNC1D+Bh5TT7PEonENU99lruKtZfKcMpRtVF6WycW5ZlYok4lRCEBBvbjtGgr\nIHnqc8WazwKBgD0oHilDjQI4fJBtiY3uD0F8ePxYtEk6z9kjMaVat2my8DycbKVJ\nlCIRLguEIcXZuSlB4D5UGmdu5G5eTvpUdy5Go8huTLZyMvBdn5AZQJuxCH6+sTA/\nI3OGrf2jmpeWkrPCdpqKbOlc6g/5RJ78BFMiJVkJO4kkNWtnGF3xisUZAoGAJ8VT\n2GHxzC7CuvUNWYunfErXyFDMwvPttdy2nzUwMYyaQedi/yr8Dh2TOfsJ1hqMfSNt\n2nkl0t4ZVmj4Y56T71z09zzXGxduiTjehrbRgzUzHzu4P4vtQD/au/5MMaTZ+i4j\nh69Bs5fIriYFiaAyWfEVDXQvf6IChNiqVgDiPJkCgYEAooIiW4HHVUNGMnIeB7UI\nBXv5gSs2heHYSmEK+Er7In5cfJQzkcJvwiOMfOPCNuwVPn+ow5IN8le1acDon5I2\n0OsXhWmgyg9zmgguj273mH3h6+o6XTg5GrEYgPVpU3m2dJkd05oWhQvzy7/OxHs8\nE4ZMz97uqmU2r8XJCo//tv8=\n-----END PRIVATE KEY-----\n"
|
||||||
|
GOOGLE_SHEET_ID=12X6qeU0W4ZDw00vS4OreyC4nFjKBeBYo7rq3wyRsrNQ
|
||||||
|
|
||||||
|
# Archivo de variables de entorno para la configuración de envío de emails
|
||||||
|
EMAIL_API_KEY=9UShpS8oh5Iun92TJSfevElI3Lp99TCv
|
||||||
23
.env.example
|
|
@ -1,23 +0,0 @@
|
||||||
# Cloudflare Turnstile — public key (visible in frontend)
|
|
||||||
TURNSTILE_SITE_KEY=0x4AA...
|
|
||||||
|
|
||||||
# Cloudflare Turnstile — secret key (server-side, keep safe!)
|
|
||||||
# In production, set this as a Gitea Actions secret named TURNSTILE_SECRET_KEY
|
|
||||||
TURNSTILE_SECRET_KEY=0x4AA...
|
|
||||||
|
|
||||||
# Supabase PostgreSQL
|
|
||||||
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
|
|
||||||
DIRECT_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
|
|
||||||
SUPABASE_URL="http://localhost:8000"
|
|
||||||
SUPABASE_ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
|
|
||||||
SUPABASE_SERVICE_ROLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
||||||
POSTGRES_PASSWORD=postgres
|
|
||||||
|
|
||||||
# Admin auth — API key (para consumo externo de /api/admin/*)
|
|
||||||
ADMIN_API_KEY="CHANGE_ME_admin_api_key"
|
|
||||||
|
|
||||||
# Admin auth — credenciales del seed (solo se usan en scripts/seed-admin.ts)
|
|
||||||
ADMIN_EMAIL="admin@example.com"
|
|
||||||
ADMIN_USERNAME="admin"
|
|
||||||
ADMIN_PASSWORD="CHANGE_ME_password"
|
|
||||||
ADMIN_NOMBRE="Admin"
|
|
||||||
|
|
@ -1,72 +1,14 @@
|
||||||
name: Deploy cdrdpyj
|
name: Centro del Reino de Paz y Justicia
|
||||||
|
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
branches: [staging, production]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
explore-gitea-actions:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
- name: Set target dir & PM2 env
|
- name: List files in the repository
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ gitea.ref_name }}" = "production" ]; then
|
ls ${{ gitea.workspace }}
|
||||||
echo "TARGET_DIR=/var/www/node/cdrdpyj" >> $GITHUB_ENV
|
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||||
echo "APP_NAME=cdrdpyj-live" >> $GITHUB_ENV
|
|
||||||
else
|
|
||||||
echo "TARGET_DIR=/var/www/node/dev.cdrdjyp" >> $GITHUB_ENV
|
|
||||||
echo "APP_NAME=cdrdpyj" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 11
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '22'
|
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
|
||||||
- run: pnpm run build
|
|
||||||
|
|
||||||
- name: Copy build to VPS
|
|
||||||
uses: appleboy/scp-action@master
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.VPS_HOST }}
|
|
||||||
username: ${{ secrets.VPS_USER }}
|
|
||||||
key: ${{ secrets.VPS_SSH_KEY }}
|
|
||||||
source: "dist/*,package.json,pnpm-lock.yaml,pnpm-workspace.yaml,ecosystem.config.cjs,prisma/schema.prisma,prisma/migrations,prisma.config.ts"
|
|
||||||
target: "${{ env.TARGET_DIR }}"
|
|
||||||
|
|
||||||
- name: Restart PM2
|
|
||||||
uses: appleboy/ssh-action@master
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.VPS_HOST }}
|
|
||||||
username: ${{ secrets.VPS_USER }}
|
|
||||||
key: ${{ secrets.VPS_SSH_KEY }}
|
|
||||||
script: |
|
|
||||||
set -e
|
|
||||||
export NVM_DIR="$HOME/.nvm"
|
|
||||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
||||||
npm install -g pnpm@11 2>&1
|
|
||||||
cd ${{ env.TARGET_DIR }}
|
|
||||||
cat > .env <<'ENVEOF'
|
|
||||||
DATABASE_URL="${{ secrets.DATABASE_URL }}"
|
|
||||||
DIRECT_URL="${{ secrets.DIRECT_URL }}"
|
|
||||||
GOOGLE_SERVICE_ACCOUNT_EMAIL="${{ secrets.GOOGLE_SERVICE_ACCOUNT_EMAIL }}"
|
|
||||||
GOOGLE_PRIVATE_KEY="${{ secrets.GOOGLE_PRIVATE_KEY }}"
|
|
||||||
GOOGLE_SHEET_ID="${{ secrets.GOOGLE_SHEET_ID }}"
|
|
||||||
EMAIL_API_KEY="${{ secrets.EMAIL_API_KEY }}"
|
|
||||||
TURNSTILE_SITE_KEY="${{ secrets.TURNSTILE_SITE_KEY }}"
|
|
||||||
TURNSTILE_SECRET_KEY="${{ secrets.TURNSTILE_SECRET_KEY }}"
|
|
||||||
CLOUDFLARE_API_TOKEN="${{ secrets.CLOUDFLARE_API_TOKEN }}"
|
|
||||||
CLOUDFLARE_ACCOUNT_ID="${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"
|
|
||||||
ADMIN_API_KEY="${{ secrets.ADMIN_API_KEY }}"
|
|
||||||
ENVEOF
|
|
||||||
pnpm install --prod 2>&1
|
|
||||||
pnpm exec prisma generate 2>&1
|
|
||||||
pnpm exec prisma migrate deploy 2>&1
|
|
||||||
pm2 reload ecosystem.config.cjs --only ${{ env.APP_NAME }} --update-env || \
|
|
||||||
pm2 start ecosystem.config.cjs --only ${{ env.APP_NAME }} --update-env
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ pnpm-debug.log*
|
||||||
|
|
||||||
|
|
||||||
# environment variables
|
# environment variables
|
||||||
.env
|
|
||||||
.env.keys
|
.env.keys
|
||||||
|
|
||||||
# macOS-specific files
|
# macOS-specific files
|
||||||
|
|
@ -22,22 +21,3 @@ pnpm-debug.log*
|
||||||
|
|
||||||
# jetbrains setting folder
|
# jetbrains setting folder
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
/generated/prisma
|
|
||||||
prisma/*.db
|
|
||||||
prisma/dev.db
|
|
||||||
data/
|
|
||||||
|
|
||||||
# opencode - agentes y scripts locales (no subir a producción)
|
|
||||||
opencode/
|
|
||||||
.opencode/
|
|
||||||
docs/
|
|
||||||
|
|
||||||
# guía técnica local
|
|
||||||
docs/GUIA-TECNICA.md
|
|
||||||
|
|
||||||
# scripts de migración (locales, no en producción)
|
|
||||||
scripts/migrate-sheets-to-db.ts
|
|
||||||
scripts/seed-form-config.ts
|
|
||||||
scripts/
|
|
||||||
.env.example
|
|
||||||
|
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
---
|
|
||||||
name: dynamic-form
|
|
||||||
description: Use when working with the volunteer registration dynamic multi-step form. Relevant files: DynamicForm.vue, formulario-inscripcion.json, [section]/index.astro, i18n system, reglamento HTML.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Dynamic Multi-Step Volunteer Registration Form
|
|
||||||
|
|
||||||
## Stack
|
|
||||||
|
|
||||||
- **Framework:** Astro (SSR, `output: "server"`, Node.js standalone)
|
|
||||||
- **UI:** Vue 3 + Tailwind CSS v4 + daisyUI v5
|
|
||||||
- **i18n:** Astro built-in i18n with `prefixDefaultLocale: true`, custom translator via `createTranslator(locale)`
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Form Config (JSON-driven)
|
|
||||||
|
|
||||||
The form structure is defined in `public/forms/formulario-inscripcion.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action": "/api/formulario/send",
|
|
||||||
"submit_label": "form.submit",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"label": "form.step1_reglamento",
|
|
||||||
"fields": [ ... ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Each field supports:
|
|
||||||
- `type`: `text`, `email`, `phone`, `date`, `textarea`, `radio`, `checkbox`, `select`, `autocomplete`
|
|
||||||
- `required`: boolean (for checkbox, individual options can also have `required: true`)
|
|
||||||
- `colspan`: `2` or `3` for grid layout when step has `column: 2` or `column: 3`
|
|
||||||
- `readonly`: displays value from `formData` (shared across steps). Supports `valueFrom` to reference another field's key.
|
|
||||||
- `showWhen`: `{ field: "other_key", value: "expected_value" }` — conditional display; for checkboxes checks array inclusion
|
|
||||||
- `levels`: proficiency radios for each selected checkbox option (e.g., Básico/Intermedio/Avanzado)
|
|
||||||
- `placeholder`: translation key for placeholder text
|
|
||||||
- `source`: URL to JSON file for `select`/`autocomplete` options (e.g., `/forms/paises.json`)
|
|
||||||
|
|
||||||
### Key Files
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `src/components/forms/DynamicForm.vue` | Core form component (751 lines) |
|
|
||||||
| `public/forms/formulario-inscripcion.json` | Form structure config (8 steps) |
|
|
||||||
| `public/forms/paises.json` | Country list for `select`/`autocomplete` |
|
|
||||||
| `src/pages/[locale]/[section]/index.astro` | Routes news, editorial, AND formulario |
|
|
||||||
| `src/i18n/index.ts` | Translator, `routeTranslations`, `I18nKey` type |
|
|
||||||
| `src/i18n/es.json` | Spanish translations (all form keys) |
|
|
||||||
| `public/reglamento/es.html` | Reglamento content (section-based HTML) |
|
|
||||||
|
|
||||||
### Field Types
|
|
||||||
|
|
||||||
| Type | Rendering | Behavior |
|
|
||||||
|------|-----------|----------|
|
|
||||||
| `text` | `<input>` inside daisyUI `<label class="input">` | Phosphor icon via `getFieldIcon()` |
|
|
||||||
| `email` | Same as text, `type="email"` | Regex validation on non-empty |
|
|
||||||
| `phone` | Same as text, `type="tel"` | Regex `/^\d+$/` — strips non-digit chars on input |
|
|
||||||
| `phone_country` | daisyUI `join` with autocomplete input (left) + `<input type="tel">` (right) | Input filters countries by name or code as you type. Dropdown shows only `🇨🇴 +57`. On select, stores `dial_code` in `phoneParts[key].code` and combines with number in `formData[key]`. Selected display shows `🇨🇴 +57`. |
|
|
||||||
| `date` | `<input type="date">` | Calendar icon |
|
|
||||||
| `textarea` | `<textarea>` with absolute icon | 4 rows, `resize-none` |
|
|
||||||
| `radio` | Inline `<input type="radio">` | `flex flex-wrap gap-x-5 gap-y-1` |
|
|
||||||
| `checkbox` | Stacked checkboxes with optional `levels` radios | Array in `formData` |
|
|
||||||
| `select` | `<select>` populated from `field.source` JSON | `getSelectOptions(field)` loads & caches |
|
|
||||||
| `autocomplete` | `<input>` with dropdown suggestions | `filteredSuggestions()` filters by input |
|
|
||||||
|
|
||||||
### DynamicForm.vue Features
|
|
||||||
|
|
||||||
- **Multi-step navigation:** stepper with numbered circles + step labels, clickable to revisit completed steps. Gold (`#CBA16A`) for active, cream (`#EBE6D2`) with checkmark for completed.
|
|
||||||
- **Validation:** per-step via `validateStep()`; checks required fields (with trim), email format, checkbox required options, level selection. Errors show `ph:warning-circle` icon + "Este campo es obligatorio".
|
|
||||||
- **Step counter:** "Paso X de Y" centered above buttons on mobile, inline with "Siguiente" on desktop. Divider line separates fields from navigation.
|
|
||||||
- **Reglamento scroll requirement:** fetches HTML from `/reglamento/{locale}.html` with fallback to `es`, renders in `max-h-[500px] md:max-h-[720px] overflow-y-auto`. User must scroll to bottom (`scrollTop + clientHeight >= scrollHeight - 10`) before checkboxes (step 1) and "Siguiente" button become enabled. Info banner + tooltip shown until requirement met.
|
|
||||||
- **Conditional fields:** `shouldShow()` evaluates `showWhen`; for checkboxes source, checks array inclusion; for others, strict equality.
|
|
||||||
- **Levels system:** when checkbox option is selected, level radios appear inline (`ml-9 mt-1`). Levels also validated.
|
|
||||||
- **Readonly fields:** display data from other steps via `valueFrom` cross-reference.
|
|
||||||
- **Select/autocomplete:** lazy-loads options from `field.source` URL, cached in `suggestionsCache`. Autocomplete filters by input value, shows dropdown on focus/input.
|
|
||||||
- **Icons:** Phosphor icons mapped via `getFieldIcon()` by field key or type.
|
|
||||||
- **Submit:** POSTs `{ formData, responses, turnstileToken, honeypot }` to config's `action` URL (`/api/formulario/send`). Success screen shows logo (`/img/logo-metalico.webp`), success title, info detail, and "Volver al inicio" link. Handles loading/spinner state during submit.
|
|
||||||
- **Bot protection:** Cloudflare Turnstile widget renders on the last step. `turnstileToken` ref updated via callback. Honeypot hidden field (`name="website"`, `class="hidden"`, `tabindex="-1"`) traps basic bots. Both values included in payload.
|
|
||||||
- **Payload shape:** `responses` array with `{ key, value, section_id: "step_N" }`. For levels, each level is a separate response entry. Does NOT include empty fields. Extra fields: `turnstileToken` (string), `honeypot` (string).
|
|
||||||
- **Mount reset:** `isSuccess.value = false` on fetch to prevent stale success state on re-navigation.
|
|
||||||
|
|
||||||
### Validation Logic (validateStep)
|
|
||||||
|
|
||||||
- **Checkbox required:** if individual options have `required: true`, all must be selected; if no option is individually required but field is `required`, at least 1 selection is needed
|
|
||||||
- **Text/email/phone/date/textarea/radio required:** checks `!val || val.trim() === ""`
|
|
||||||
- **Phone format:** validates `/^\d+$/` when non-empty — `formatErrors` tracks format issues separately from `stepErrors`; shows "Solo se permiten números" vs "Este campo es obligatorio"
|
|
||||||
- **Phone country (`phone_country`):** two-piece component (select + input). `phoneParts` reactive tracks code and number separately; combined value stored in `formData[key]`. Input sanitizes non-digits via `event.target.value = cleaned` + `phoneParts` tracking. Validates: required (code + number filled), min 7 digits, max 15 total (code + number).
|
|
||||||
|
|
||||||
### i18n System
|
|
||||||
|
|
||||||
- `createTranslator(locale)` returns `tl(key, vars?)` function — supports `{name}` interpolation (used in `form.select_placeholder`)
|
|
||||||
- `I18nKey = keyof typeof es` — all keys must exist in `es.json`
|
|
||||||
- Fallback chain: requested locale → `es` → raw key string
|
|
||||||
- `routeTranslations` now includes `formulario` key (was missing initially):
|
|
||||||
|
|
||||||
```ts
|
|
||||||
formulario: {
|
|
||||||
es: "formulario", en: "form", fr: "formulaire",
|
|
||||||
he: "טופס", uk: "форма", pt: "formulário",
|
|
||||||
ru: "форма", rw: "formulaire", kr: "fòm"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `getRouteKeyFromSlug(slug)`: resolves URL segment to route key (returns `"news"` default for unknown)
|
|
||||||
- `getLocalizedRoute(route, locale)`: builds locale-aware URL segment
|
|
||||||
|
|
||||||
### Routing
|
|
||||||
|
|
||||||
The `[section]/index.astro` page handles three route keys:
|
|
||||||
- `"formulario"` + locale `es` → renders DynamicForm with MainLayout
|
|
||||||
- `"formulario"` + other locale → `Astro.redirect` to that locale's home page
|
|
||||||
- `"news"` / `"editorial"` → existing content list behavior
|
|
||||||
|
|
||||||
Form URLs:
|
|
||||||
- `/es/formulario` (active)
|
|
||||||
- `/en/form`, `/fr/formulaire`, etc. (redirect to home)
|
|
||||||
|
|
||||||
### Color Palette
|
|
||||||
|
|
||||||
| Token | Hex | Usage |
|
|
||||||
|-------|-----|-------|
|
|
||||||
| Primary green | `#22523F` | Headings, stepper active, buttons, reglamento headings, focus outlines, hover backgrounds |
|
|
||||||
| Cream | `#EBE6D2` | Form background, stepper completed circles |
|
|
||||||
| Gold | `#CBA16A` | Active step circles |
|
|
||||||
| Input text | `#1a1a1a` | Input/textarea values, checkbox/radio labels |
|
|
||||||
| Readonly text | `#6B7280` | Readonly field values |
|
|
||||||
| Checked accent | `#4A8C6F` | Checkbox/radio checked background and border |
|
|
||||||
|
|
||||||
### Responsive Behavior
|
|
||||||
|
|
||||||
| Element | Mobile (< sm) | Desktop (sm+) |
|
|
||||||
|---------|---------------|---------------|
|
|
||||||
| Container | `max-w-3xl px-4` | `max-w-3xl mx-auto` |
|
|
||||||
| Form padding | `p-5` | `sm:p-8 lg:p-10` |
|
|
||||||
| Grid gap | `gap-4` | `sm:gap-5` |
|
|
||||||
| Title size | `text-lg` | `sm:text-xl` |
|
|
||||||
| Button font | `text-xs` | `sm:text-sm` |
|
|
||||||
| Step counter | Centered above buttons | Next to "Siguiente" button |
|
|
||||||
| Nav layout | Column (counter, then row of buttons) | Row with `justify-between` via `sm:contents` |
|
|
||||||
| Reglamento height | `max-h-[500px]` | `md:max-h-[720px]` |
|
|
||||||
|
|
||||||
### API Endpoint: `POST /api/formulario/send`
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `src/pages/api/formulario/send.ts` | Receives form data, validates Turnstile, writes to Google Sheets |
|
|
||||||
|
|
||||||
**Security checks (in order):**
|
|
||||||
1. **Honeypot** — if `body.honeypot` is non-empty → `403 Solicitud rechazada`
|
|
||||||
2. **Turnstile** — verifies `body.turnstileToken` against Cloudflare API → `403 Captcha inválido` if fail
|
|
||||||
3. If `TURNSTILE_SECRET_KEY` env var is empty/unset, Turnstile check is skipped (dev mode)
|
|
||||||
|
|
||||||
**Env vars needed at runtime:**
|
|
||||||
- `TURNSTILE_SITE_KEY` — public key (in `ecosystem.config.cjs`, injected via `sed` in CI)
|
|
||||||
- `TURNSTILE_SECRET_KEY` — secret key (injected from `secrets.TURNSTILE_SECRET_KEY` in CI)
|
|
||||||
|
|
||||||
### Reglamento HTML
|
|
||||||
|
|
||||||
Stored in `public/reglamento/{locale}.html`. Must NOT contain `<html>`, `<head>`, `<body>`, or `<style>` tags — only `<section>`, `<h1>`, `<h2>`, `<p>`, `<ul>`, `<li>` elements. Loaded via `fetch()` and injected with `v-html` inside a `.reglamento-content` div with scoped CSS styles in the component's `<style>` block.
|
|
||||||
|
|
||||||
## Important Conventions
|
|
||||||
|
|
||||||
- NEVER run `pnpm run build` as a verification step — the user will handle builds manually or via CI.
|
|
||||||
- Translation keys in `es.json` use dot notation: `"form.field_name": "Label"`
|
|
||||||
- Checkbox `formData` is initialized as `[]`, other fields as `""`
|
|
||||||
- Step labels: `form.step1_reglamento`, `form.step2`–`form.step8`
|
|
||||||
- The `RegisterModal` on the home page was replaced with a direct link to `/{locale}/{formSlug}`
|
|
||||||
- All i18n keys used in DynamicForm.vue must exist in `es.json` (strict `I18nKey` typing)
|
|
||||||
- Input icons are mapped via `getFieldIcon()` by key or type — add new entries when adding fields (uses `ph:` prefix Phosphor icons)
|
|
||||||
- `valueFrom` on `readonly` fields allows displaying cross-step data (e.g., show `nombre` from step 2 on step 8)
|
|
||||||
- `select` and `autocomplete` fields require a `source` URL pointing to a JSON array of `{ label, value }` objects
|
|
||||||
- `suggestionsCache` is a shared ref — data loads once per `source` URL and is reused across all fields pointing to the same source
|
|
||||||
- Reglamento is fetched via locale fallback chain: `props.locale` → `"es"` — only fetched once per step 0 visit via `reglamentoFetchAttempted` guard
|
|
||||||
- Turnstile widget renders only on the last step (`isLastStep`) and only if `props.turnstileSiteKey` is non-empty. The token is obtained via `window.turnstile.render()` callback. Script loads from `https://challenges.cloudflare.com/turnstile/v0/api.js` on `onMounted`.
|
|
||||||
- Honeypot field (`name="website"`) is hidden via daisyUI `hidden` class and `tabindex="-1"` — browsers/autofill may still fill it but human users never see it.
|
|
||||||
|
|
||||||
## Language Style
|
|
||||||
|
|
||||||
- All Spanish text must use **international Spanish (neutral/formal)**, NOT Argentine voseo.
|
|
||||||
- Use **usted** forms: "Seleccione", "Indique", "Complete", "Ingrese", "Inténtelo", "Desplácese", "Debe leer", etc.
|
|
||||||
- Use **su** instead of **tu**: "su país", "su interés", "sus datos".
|
|
||||||
- Exception: the `formulario-inscripcion.json` field labels and option labels can keep their existing text — only new text generated for `_help` tooltips or translations must follow this rule.
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
"allowEmptyTranslations": false,
|
|
||||||
"defaultLanguage": "en",
|
|
||||||
"forceKeyUPPERCASE": true,
|
|
||||||
"jsonSpace": 2,
|
|
||||||
"keySeparator": ".",
|
|
||||||
"lineEnding": "\n",
|
|
||||||
"supportedFolders": [
|
|
||||||
"i18n"
|
|
||||||
],
|
|
||||||
"workspaceFolders": [
|
|
||||||
{
|
|
||||||
"name": "src",
|
|
||||||
"path": "src/i18n",
|
|
||||||
"visibleColumns": [
|
|
||||||
"es",
|
|
||||||
"fr",
|
|
||||||
"he",
|
|
||||||
"pt",
|
|
||||||
"uk"
|
|
||||||
],
|
|
||||||
"hiddenColumns": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"defaultWorkspaceFolder": "src",
|
|
||||||
"translationService": "Coming soon",
|
|
||||||
"translationServiceApiKey": "Coming soon"
|
|
||||||
}
|
|
||||||
|
|
@ -44,4 +44,4 @@ Feel free to check [our documentation](https://docs.astro.build) or jump into ou
|
||||||
|
|
||||||
Adding gitea/workflows/deploy.yaml to test github ci/cd runner
|
Adding gitea/workflows/deploy.yaml to test github ci/cd runner
|
||||||
|
|
||||||
Testing runner change spmeting v12
|
Testing runner
|
||||||
|
|
@ -7,29 +7,24 @@ import icon from "astro-icon";
|
||||||
import node from "@astrojs/node";
|
import node from "@astrojs/node";
|
||||||
|
|
||||||
import vue from "@astrojs/vue";
|
import vue from "@astrojs/vue";
|
||||||
import react from "@astrojs/react";
|
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()],
|
plugins: [tailwindcss()],
|
||||||
},
|
},
|
||||||
site: "https://centrodelreinodepazyjusticia.com/",
|
|
||||||
//base: '/mockup/',
|
//base: '/mockup/',
|
||||||
|
|
||||||
integrations: [markdoc(), icon(), vue(), react()],
|
integrations: [markdoc(), icon(), vue()],
|
||||||
|
|
||||||
i18n: {
|
i18n: {
|
||||||
locales: ["es", "en", "fr", "he", "uk", "pt", "ru", "rw", "kr"],
|
locales: ["es", "en", "fr", "he", "uk", "pt-br"],
|
||||||
defaultLocale: "es",
|
defaultLocale: "es",
|
||||||
routing: {
|
|
||||||
prefixDefaultLocale: true,
|
|
||||||
redirectToDefaultLocale: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
image: {
|
image: {
|
||||||
domains: ['placehold.co', 'ik.imagekit.io', 'picsum.photos'],
|
domains: ['placehold.co','ik.imagekit.io','picsum.photos'],
|
||||||
service: imageService(),
|
service: imageService(),
|
||||||
},
|
},
|
||||||
output: "server",
|
output: "server",
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
apps: [
|
|
||||||
{
|
|
||||||
name: "cdrdpyj",
|
|
||||||
cwd: __dirname,
|
|
||||||
script: "dist/server/entry.mjs",
|
|
||||||
interpreter_args: "--env-file=.env",
|
|
||||||
env: {
|
|
||||||
NODE_ENV: "staging",
|
|
||||||
PORT: 3310,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "cdrdpyj-live",
|
|
||||||
cwd: __dirname,
|
|
||||||
script: "dist/server/entry.mjs",
|
|
||||||
interpreter_args: "--env-file=.env",
|
|
||||||
env: {
|
|
||||||
NODE_ENV: "production",
|
|
||||||
PORT: 4321,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
26
package.json
|
|
@ -1,22 +1,17 @@
|
||||||
{
|
{
|
||||||
"name": "cdrdpyj",
|
"name": "",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"postbuild": "node scripts/send-to-n8n.js",
|
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro",
|
"astro": "astro"
|
||||||
"db:migrate-sheets": "npx tsx scripts/migrate-sheets-to-db.ts",
|
|
||||||
"db:seed-form-config": "npx tsx scripts/seed-form-config.ts",
|
|
||||||
"db:setup": "npx tsx scripts/seed-form-config.ts && npx tsx scripts/migrate-sheets-to-db.ts"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/markdoc": "^2.0.3",
|
"@astrojs/markdoc": "^0.15.10",
|
||||||
"@astrojs/node": "^11.0.2",
|
"@astrojs/node": "^9.5.3",
|
||||||
"@astrojs/react": "^6.0.1",
|
"@astrojs/vue": "^5.1.4",
|
||||||
"@astrojs/vue": "^7.0.1",
|
|
||||||
"@coreui/icons": "^3.0.1",
|
"@coreui/icons": "^3.0.1",
|
||||||
"@dotenvx/dotenvx": "^1.52.0",
|
"@dotenvx/dotenvx": "^1.52.0",
|
||||||
"@fontsource-variable/kameron": "^5.2.8",
|
"@fontsource-variable/kameron": "^5.2.8",
|
||||||
|
|
@ -25,27 +20,20 @@
|
||||||
"@fontsource/poppins": "^5.2.7",
|
"@fontsource/poppins": "^5.2.7",
|
||||||
"@iconify-json/ph": "^1.2.2",
|
"@iconify-json/ph": "^1.2.2",
|
||||||
"@iconify/vue": "^5.0.0",
|
"@iconify/vue": "^5.0.0",
|
||||||
"@prisma/client": "^6.19.2",
|
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@unpic/astro": "^1.0.2",
|
"@unpic/astro": "^1.0.2",
|
||||||
"astro": "^7.0.6",
|
"astro": "^5.17.1",
|
||||||
"astro-embed": "^0.12.0",
|
"astro-embed": "^0.12.0",
|
||||||
"astro-google-analytics": "^1.0.3",
|
"astro-google-analytics": "^1.0.3",
|
||||||
"astro-icon": "^1.1.5",
|
"astro-icon": "^1.1.5",
|
||||||
"cloudflare": "^7.0.0",
|
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"googleapis": "^171.4.0",
|
"googleapis": "^171.4.0",
|
||||||
"prisma": "^6.19.2",
|
|
||||||
"react": "^19.2.5",
|
|
||||||
"react-dom": "^19.2.5",
|
|
||||||
"sharp": "^0.34.5",
|
|
||||||
"swiper": "^12.1.0",
|
"swiper": "^12.1.0",
|
||||||
"tailwindcss": "^4.1.18",
|
"tailwindcss": "^4.1.18",
|
||||||
"vue": "^3.5.28"
|
"vue": "^3.5.28"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.19",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"daisyui": "^5.5.18",
|
"daisyui": "^5.5.18"
|
||||||
"dotenv": "^17.4.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5888
pnpm-lock.yaml
|
|
@ -1,9 +0,0 @@
|
||||||
allowBuilds:
|
|
||||||
'@prisma/client': true
|
|
||||||
'@prisma/engines': true
|
|
||||||
better-sqlite3: true
|
|
||||||
core-js: true
|
|
||||||
esbuild: true
|
|
||||||
prisma: true
|
|
||||||
protobufjs: true
|
|
||||||
sharp: true
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
|
|
||||||
// This file was generated by Prisma and assumes you have installed the following:
|
|
||||||
// npm install --save-dev prisma dotenv
|
|
||||||
import "dotenv/config";
|
|
||||||
import { defineConfig } from "prisma/config";
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
schema: "prisma/schema.prisma",
|
|
||||||
migrations: {
|
|
||||||
path: "prisma/migrations",
|
|
||||||
},
|
|
||||||
engine: "classic",
|
|
||||||
datasource: {
|
|
||||||
url:
|
|
||||||
process.env.DIRECT_URL ||
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://localhost:5432/postgres?schema=public",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "Contact" (
|
|
||||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"mensaje" TEXT NOT NULL,
|
|
||||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "Contact_email_createdAt_idx" ON "Contact"("email", "createdAt");
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- Added the required column `updatedAt` to the `Contact` table without a default value. This is not possible if the table is not empty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- RedefineTables
|
|
||||||
PRAGMA defer_foreign_keys=ON;
|
|
||||||
PRAGMA foreign_keys=OFF;
|
|
||||||
CREATE TABLE "new_Contact" (
|
|
||||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"mensaje" TEXT NOT NULL,
|
|
||||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" DATETIME NOT NULL
|
|
||||||
);
|
|
||||||
INSERT INTO "new_Contact" ("createdAt", "email", "id", "mensaje", "nombre") SELECT "createdAt", "email", "id", "mensaje", "nombre" FROM "Contact";
|
|
||||||
DROP TABLE "Contact";
|
|
||||||
ALTER TABLE "new_Contact" RENAME TO "Contact";
|
|
||||||
CREATE UNIQUE INDEX "Contact_email_key" ON "Contact"("email");
|
|
||||||
CREATE INDEX "Contact_email_createdAt_idx" ON "Contact"("email", "createdAt");
|
|
||||||
PRAGMA foreign_keys=ON;
|
|
||||||
PRAGMA defer_foreign_keys=OFF;
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Please do not edit this file manually
|
|
||||||
# It should be added in your version-control system (e.g., Git)
|
|
||||||
provider = "sqlite"
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "Contact" (
|
|
||||||
"id" SERIAL NOT NULL,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"mensaje" TEXT NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "Contact_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "Contact_email_key" ON "Contact"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "Contact_email_createdAt_idx" ON "Contact"("email", "createdAt");
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the `Contact` table. If the table is not empty, all the data it contains will be lost.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- DropTable
|
|
||||||
DROP TABLE "Contact";
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "contact" (
|
|
||||||
"id" SERIAL NOT NULL,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"mensaje" TEXT NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "contact_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "formularios" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"numero_voluntario" SERIAL NOT NULL,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"segundo_nombre" TEXT,
|
|
||||||
"apellido" TEXT NOT NULL,
|
|
||||||
"documento_nro" TEXT,
|
|
||||||
"documento_tipo" TEXT,
|
|
||||||
"correo" TEXT NOT NULL,
|
|
||||||
"fecha_nacimiento" DATE,
|
|
||||||
"nacionalidad" TEXT,
|
|
||||||
"sexo" TEXT,
|
|
||||||
"direccion" TEXT,
|
|
||||||
"ciudad" TEXT,
|
|
||||||
"estado" TEXT,
|
|
||||||
"pais" TEXT,
|
|
||||||
"codigo_postal" TEXT,
|
|
||||||
"telefono" TEXT,
|
|
||||||
"whatsapp" TEXT,
|
|
||||||
"profesion" TEXT,
|
|
||||||
"lugar_trabajo" TEXT,
|
|
||||||
"nivel_academico" TEXT,
|
|
||||||
"status" TEXT NOT NULL DEFAULT 'pendiente',
|
|
||||||
"form_version" TEXT,
|
|
||||||
"email_sent_at" TIMESTAMPTZ,
|
|
||||||
"submitted_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "formularios_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "respuestas" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"formulario_id" UUID NOT NULL,
|
|
||||||
"key" TEXT NOT NULL,
|
|
||||||
"value" TEXT NOT NULL,
|
|
||||||
"seccion" TEXT NOT NULL DEFAULT '',
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "respuestas_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "secciones" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title_key" TEXT NOT NULL,
|
|
||||||
"title" TEXT,
|
|
||||||
"orden" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"columns" INTEGER NOT NULL DEFAULT 1,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "secciones_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "campos" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"key" TEXT NOT NULL,
|
|
||||||
"label_key" TEXT NOT NULL,
|
|
||||||
"tipo" TEXT NOT NULL,
|
|
||||||
"seccion_id" UUID,
|
|
||||||
"required" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"orden" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"options" JSONB,
|
|
||||||
"source" TEXT,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "campos_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "form_versions" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"version" TEXT NOT NULL,
|
|
||||||
"config" JSONB NOT NULL,
|
|
||||||
"active" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "form_versions_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "admins" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"auth_user_id" UUID NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"nombre" TEXT NOT NULL,
|
|
||||||
"rol" TEXT NOT NULL DEFAULT 'coordinador',
|
|
||||||
"activo" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"ultimo_acceso" TIMESTAMPTZ,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "admins_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "contact_email_key" ON "contact"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "contact_email_createdAt_idx" ON "contact"("email", "createdAt");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "formularios_numero_voluntario_key" ON "formularios"("numero_voluntario");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_correo_idx" ON "formularios"("correo");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_status_idx" ON "formularios"("status");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_pais_idx" ON "formularios"("pais");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_submitted_at_idx" ON "formularios"("submitted_at");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "respuestas_formulario_id_idx" ON "respuestas"("formulario_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "respuestas_key_idx" ON "respuestas"("key");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "respuestas_seccion_idx" ON "respuestas"("seccion");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "secciones_orden_idx" ON "secciones"("orden");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "campos_key_key" ON "campos"("key");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "campos_seccion_id_idx" ON "campos"("seccion_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "campos_tipo_idx" ON "campos"("tipo");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "admins_auth_user_id_key" ON "admins"("auth_user_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "admins_email_key" ON "admins"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "admins_email_idx" ON "admins"("email");
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "respuestas" ADD CONSTRAINT "respuestas_formulario_id_fkey" FOREIGN KEY ("formulario_id") REFERENCES "formularios"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "campos" ADD CONSTRAINT "campos_seccion_id_fkey" FOREIGN KEY ("seccion_id") REFERENCES "secciones"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
-- Enable pg_trgm for trigram-based GIN indexes
|
|
||||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_nombre_trgm_idx" ON "formularios" USING GIN ("nombre" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_apellido_trgm_idx" ON "formularios" USING GIN ("apellido" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_correo_trgm_idx" ON "formularios" USING GIN ("correo" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_telefono_trgm_idx" ON "formularios" USING GIN ("telefono" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_whatsapp_trgm_idx" ON "formularios" USING GIN ("whatsapp" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_documento_nro_trgm_idx" ON "formularios" USING GIN ("documento_nro" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "respuestas_value_trgm_idx" ON "respuestas" USING GIN ("value" gin_trgm_ops);
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_ciudad_trgm_idx" ON "formularios" USING GIN ("ciudad" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_estado_trgm_idx" ON "formularios" USING GIN ("estado" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_profesion_trgm_idx" ON "formularios" USING GIN ("profesion" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_nivel_academico_trgm_idx" ON "formularios" USING GIN ("nivel_academico" gin_trgm_ops);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "formularios_nacionalidad_trgm_idx" ON "formularios" USING GIN ("nacionalidad" gin_trgm_ops);
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "admins" ALTER COLUMN "auth_user_id" DROP NOT NULL;
|
|
||||||
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "admins" ADD COLUMN "password_hash" TEXT;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "sessions" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"token_hash" TEXT NOT NULL,
|
|
||||||
"admin_id" UUID NOT NULL,
|
|
||||||
"expires_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "sessions_token_hash_key" ON "sessions"("token_hash");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "sessions_admin_id_idx" ON "sessions"("admin_id");
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_admin_id_fkey" FOREIGN KEY ("admin_id") REFERENCES "admins"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "admins" ADD COLUMN "username" TEXT;
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "admins_username_key" ON "admins"("username");
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Please do not edit this file manually
|
|
||||||
# It should be added in your version-control system (e.g., Git)
|
|
||||||
provider = "postgresql"
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
||||||
generator client {
|
|
||||||
provider = "prisma-client-js"
|
|
||||||
}
|
|
||||||
|
|
||||||
datasource db {
|
|
||||||
provider = "postgresql"
|
|
||||||
url = env("DATABASE_URL")
|
|
||||||
directUrl = env("DIRECT_URL")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Contact {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
nombre String
|
|
||||||
email String @unique
|
|
||||||
mensaje String
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
@@index([email, createdAt])
|
|
||||||
@@map("contact")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Formulario {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
numero_voluntario Int @unique @default(autoincrement())
|
|
||||||
nombre String
|
|
||||||
segundo_nombre String?
|
|
||||||
apellido String
|
|
||||||
documento_nro String?
|
|
||||||
documento_tipo String?
|
|
||||||
correo String
|
|
||||||
fecha_nacimiento DateTime? @db.Date
|
|
||||||
nacionalidad String?
|
|
||||||
sexo String?
|
|
||||||
direccion String?
|
|
||||||
ciudad String?
|
|
||||||
estado String?
|
|
||||||
pais String?
|
|
||||||
codigo_postal String?
|
|
||||||
telefono String?
|
|
||||||
whatsapp String?
|
|
||||||
profesion String?
|
|
||||||
lugar_trabajo String?
|
|
||||||
nivel_academico String?
|
|
||||||
status String @default("pendiente")
|
|
||||||
form_version String?
|
|
||||||
email_sent_at DateTime? @db.Timestamptz
|
|
||||||
submitted_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
updated_at DateTime @updatedAt @db.Timestamptz
|
|
||||||
|
|
||||||
respuestas Respuesta[]
|
|
||||||
|
|
||||||
@@index([correo])
|
|
||||||
@@index([status])
|
|
||||||
@@index([pais])
|
|
||||||
@@index([submitted_at])
|
|
||||||
@@index([nombre(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_nombre_trgm_idx")
|
|
||||||
@@index([apellido(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_apellido_trgm_idx")
|
|
||||||
@@index([correo(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_correo_trgm_idx")
|
|
||||||
@@index([telefono(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_telefono_trgm_idx")
|
|
||||||
@@index([whatsapp(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_whatsapp_trgm_idx")
|
|
||||||
@@index([documento_nro(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_documento_nro_trgm_idx")
|
|
||||||
@@index([ciudad(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_ciudad_trgm_idx")
|
|
||||||
@@index([estado(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_estado_trgm_idx")
|
|
||||||
@@index([profesion(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_profesion_trgm_idx")
|
|
||||||
@@index([nivel_academico(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_nivel_academico_trgm_idx")
|
|
||||||
@@index([nacionalidad(ops: raw("gin_trgm_ops"))], type: Gin, map: "formularios_nacionalidad_trgm_idx")
|
|
||||||
@@map("formularios")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Respuesta {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
formulario_id String @db.Uuid
|
|
||||||
key String
|
|
||||||
value String
|
|
||||||
seccion String @default("")
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
formulario Formulario @relation(fields: [formulario_id], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@index([formulario_id])
|
|
||||||
@@index([key])
|
|
||||||
@@index([seccion])
|
|
||||||
@@index([value(ops: raw("gin_trgm_ops"))], type: Gin, map: "respuestas_value_trgm_idx")
|
|
||||||
@@map("respuestas")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Seccion {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
title_key String
|
|
||||||
title String?
|
|
||||||
orden Int @default(0)
|
|
||||||
columns Int @default(1)
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
campos Campo[]
|
|
||||||
|
|
||||||
@@index([orden])
|
|
||||||
@@map("secciones")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Campo {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
key String @unique
|
|
||||||
label_key String
|
|
||||||
tipo String
|
|
||||||
seccion_id String? @db.Uuid
|
|
||||||
required Boolean @default(false)
|
|
||||||
orden Int @default(0)
|
|
||||||
options Json? @db.JsonB
|
|
||||||
source String?
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
seccion Seccion? @relation(fields: [seccion_id], references: [id], onDelete: SetNull)
|
|
||||||
|
|
||||||
@@index([seccion_id])
|
|
||||||
@@index([tipo])
|
|
||||||
@@map("campos")
|
|
||||||
}
|
|
||||||
|
|
||||||
model FormVersion {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
version String
|
|
||||||
config Json @db.JsonB
|
|
||||||
active Boolean @default(false)
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
@@map("form_versions")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Admin {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
auth_user_id String? @unique @db.Uuid
|
|
||||||
email String @unique
|
|
||||||
username String? @unique
|
|
||||||
nombre String
|
|
||||||
password_hash String?
|
|
||||||
rol String @default("coordinador")
|
|
||||||
activo Boolean @default(true)
|
|
||||||
ultimo_acceso DateTime? @db.Timestamptz
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
sessions Session[]
|
|
||||||
|
|
||||||
@@index([email])
|
|
||||||
@@map("admins")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Session {
|
|
||||||
id String @id @default(uuid()) @db.Uuid
|
|
||||||
token_hash String @unique
|
|
||||||
admin_id String @db.Uuid
|
|
||||||
expires_at DateTime @db.Timestamptz
|
|
||||||
created_at DateTime @default(now()) @db.Timestamptz
|
|
||||||
|
|
||||||
admin Admin @relation(fields: [admin_id], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@index([admin_id])
|
|
||||||
@@map("sessions")
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 201 KiB |
|
|
@ -1,249 +0,0 @@
|
||||||
{
|
|
||||||
"action": "/api/formulario/send",
|
|
||||||
"submit_label": "form.submit",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"label": "form.step1_reglamento",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"key": "aceptacion_reglamento",
|
|
||||||
"label": "form.aceptacion_reglamento",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "leido_acepto", "label": "form.aceptacion.leido", "required": true },
|
|
||||||
{ "value": "codigo_etica", "label": "form.aceptacion.codigo_etica", "required": true },
|
|
||||||
{ "value": "datos_personales", "label": "form.aceptacion.datos", "required": true },
|
|
||||||
{ "value": "participacion_voluntaria", "label": "form.aceptacion.voluntaria", "required": true },
|
|
||||||
{ "value": "informacion_verdadera", "label": "form.aceptacion.verdadera", "required": true },
|
|
||||||
{ "value": "firma_electronica_validez", "label": "form.aceptacion.firma_validez", "required": true }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step2",
|
|
||||||
"column": 2,
|
|
||||||
"fields": [
|
|
||||||
{ "key": "nombre", "label": "form.nombre", "type": "text", "required": true },
|
|
||||||
{ "key": "segundo_nombre", "label": "form.segundo_nombre", "type": "text" },
|
|
||||||
{ "key": "apellido", "label": "form.apellido", "type": "text", "required": true },
|
|
||||||
{ "key": "documentos", "label": "form.documentos", "type": "text", "required": true },
|
|
||||||
{ "key": "correo", "label": "form.correo", "type": "email", "required": true, "colspan": 2 },
|
|
||||||
{ "key": "reglamento_firma", "label": "form.reglamento_firma", "type": "text", "required": true, "colspan": 2, "placeholder": "form.reglamento_firma_placeholder" },
|
|
||||||
{ "key": "fecha_nacimiento", "label": "form.fecha_nacimiento", "type": "date", "required": true },
|
|
||||||
{ "key": "nacionalidad", "label": "form.nacionalidad", "type": "autocomplete", "required": true, "source": "/forms/paises.json" },
|
|
||||||
{
|
|
||||||
"key": "sexo",
|
|
||||||
"label": "form.sexo",
|
|
||||||
"type": "radio",
|
|
||||||
"colspan": 2,
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "M", "label": "form.sexo.m" },
|
|
||||||
{ "value": "F", "label": "form.sexo.f" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ "key": "direccion_completa", "label": "form.direccion", "type": "text", "required": true, "colspan": 2 },
|
|
||||||
{ "key": "direccion_postal", "label": "form.direccion_postal", "type": "text", "required": false, "colspan": 2 },
|
|
||||||
{ "key": "ciudad", "label": "form.ciudad", "type": "text", "required": true },
|
|
||||||
{ "key": "estado", "label": "form.estado", "type": "text" },
|
|
||||||
{ "key": "pais", "label": "form.pais", "type": "select", "required": true, "source": "/forms/paises.json" },
|
|
||||||
{ "key": "postal", "label": "form.codigo_postal", "type": "text", "required": true },
|
|
||||||
{ "key": "telefono", "label": "form.mobile", "type": "phone_country", "required": true, "source": "/forms/paises.json" },
|
|
||||||
{ "key": "whatsapp", "label": "form.whatsapp", "type": "phone_country", "source": "/forms/paises.json" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step3",
|
|
||||||
"column": 2,
|
|
||||||
"fields": [
|
|
||||||
{ "key": "profesion", "label": "form.profesion", "type": "text", "required": true },
|
|
||||||
{ "key": "lugar_trabajo_actual", "label": "form.lugar_trabajo_actual", "type": "text", "required": true },
|
|
||||||
{ "key": "nivel_academico", "label": "form.nivel_academico", "type": "text", "required": true, "colspan": 2 },
|
|
||||||
{
|
|
||||||
"key": "idioma",
|
|
||||||
"label": "form.idioma",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"colspan": 2,
|
|
||||||
"levels": {
|
|
||||||
"options": [
|
|
||||||
{ "value": "Basico", "label": "form.nivel.basico" },
|
|
||||||
{ "value": "Intermedio", "label": "form.nivel.intermedio" },
|
|
||||||
{ "value": "Avanzado", "label": "form.nivel.avanzado" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"options": [
|
|
||||||
{ "value": "Espanol", "label": "form.idioma.esp" },
|
|
||||||
{ "value": "Ingles", "label": "form.idioma.ing" },
|
|
||||||
{ "value": "Hebreo", "label": "form.idioma.heb" },
|
|
||||||
{ "value": "Portugues", "label": "form.idioma.port" },
|
|
||||||
{ "value": "Frances", "label": "form.idioma.franc" },
|
|
||||||
{ "value": "Otro", "label": "form.idioma.otro" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ "key": "idioma_otro", "label": "form.idioma_otro", "type": "text", "required": false, "colspan": 2, "showWhen": { "field": "idioma", "value": "Otro" } },
|
|
||||||
{ "key": "voluntariado_anterior", "label": "form.voluntariado_anterior", "type": "radio", "required": true, "colspan": 2, "options":
|
|
||||||
[
|
|
||||||
{ "value": "si", "label": "form.voluntariado_anterior.si" },
|
|
||||||
{ "value": "no", "label": "form.voluntariado_anterior.no" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ "key": "caso_si", "label": "form.caso_si", "type": "textarea", "required": false, "colspan": 2, "showWhen": { "field": "voluntariado_anterior", "value": "si" } }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step4",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"key": "areas_colaborar",
|
|
||||||
"label": "form.areas_colaborar",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "Ayuda Humanitaria", "label": "form.areas.ayuda_humanitaria" },
|
|
||||||
{ "value": "Educacion", "label": "form.areas.educacion" },
|
|
||||||
{ "value": "Desarrollo Comunitario", "label": "form.areas.desarrollo_comunitario" },
|
|
||||||
{ "value": "Liderazgo", "label": "form.areas.liderazgo" },
|
|
||||||
{ "value": "Logistica", "label": "form.areas.logistica" },
|
|
||||||
{ "value": "Organizacion de Eventos", "label": "form.areas.organizacion_eventos" },
|
|
||||||
{ "value": "Comunicacion Institucional", "label": "form.areas.comunicacion_institucional" },
|
|
||||||
{ "value": "Fotografia y Medios", "label": "form.areas.fotografia_medios" },
|
|
||||||
{ "value": "Recaudacion de Fondos", "label": "form.areas.recaudacion_fondos" },
|
|
||||||
{ "value": "Gestion de Proyectos", "label": "form.areas.gestion_proyectos" },
|
|
||||||
{ "value": "Traduccion e Interpretacion", "label": "form.areas.traduccion_interpretacion" },
|
|
||||||
{ "value": "Asesoria Juridica", "label": "form.areas.asesoria_juridica" },
|
|
||||||
{ "value": "Servicios Medicos", "label": "form.areas.servicios_medicos" },
|
|
||||||
{ "value": "Diplomacia Publica", "label": "form.areas.diplomacia_publica" },
|
|
||||||
{ "value": "Administracion", "label": "form.areas.administracion" },
|
|
||||||
{ "value": "Tecnologia e Innovacion", "label": "form.areas.tecnologia_innovacion" },
|
|
||||||
{ "value": "Otra", "label": "form.areas.otra" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ "key": "areas_otra", "label": "form.areas_otra", "type": "text", "required": false, "showWhen": { "field": "areas_colaborar", "value": "Otra" } }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step5",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"key": "dias_disponibles",
|
|
||||||
"label": "form.dias_disponibles",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "Lunes", "label": "form.dias.lunes" },
|
|
||||||
{ "value": "Martes", "label": "form.dias.martes" },
|
|
||||||
{ "value": "Miercoles", "label": "form.dias.miercoles" },
|
|
||||||
{ "value": "Jueves", "label": "form.dias.jueves" },
|
|
||||||
{ "value": "Viernes", "label": "form.dias.viernes" },
|
|
||||||
{ "value": "Sabado", "label": "form.dias.sabado" },
|
|
||||||
{ "value": "Domingo", "label": "form.dias.domingo" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "horario_preferido",
|
|
||||||
"label": "form.horario_preferido",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "Manana", "label": "form.horario.manana" },
|
|
||||||
{ "value": "Tarde", "label": "form.horario.tarde" },
|
|
||||||
{ "value": "Noche", "label": "form.horario.noche" },
|
|
||||||
{ "value": "Segun necesidades", "label": "form.horario.segun" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fuera_ciudad",
|
|
||||||
"label": "form.fuera_ciudad",
|
|
||||||
"type": "radio",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "si", "label": "form.si" },
|
|
||||||
{ "value": "no", "label": "form.no" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "misiones_internacionales",
|
|
||||||
"label": "form.misiones_internacionales",
|
|
||||||
"type": "radio",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "si", "label": "form.si" },
|
|
||||||
{ "value": "no", "label": "form.no" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step6",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"key": "condicion_medica",
|
|
||||||
"label": "form.condicion_medica",
|
|
||||||
"type": "radio",
|
|
||||||
"required": true,
|
|
||||||
"options": [
|
|
||||||
{ "value": "si", "label": "form.si" },
|
|
||||||
{ "value": "no", "label": "form.no" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "condicion_medica_cual",
|
|
||||||
"label": "form.condicion_medica_cual",
|
|
||||||
"type": "textarea",
|
|
||||||
"required": true,
|
|
||||||
"showWhen": { "field": "condicion_medica", "value": "si" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "alergias",
|
|
||||||
"label": "form.alergias",
|
|
||||||
"type": "textarea",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "medicamentos",
|
|
||||||
"label": "form.medicamentos",
|
|
||||||
"type": "textarea",
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step7",
|
|
||||||
"fields": [
|
|
||||||
{ "key": "emergencia_nombre", "label": "form.emergencia_nombre", "type": "text", "required": true },
|
|
||||||
{ "key": "emergencia_parentesco", "label": "form.emergencia_parentesco", "type": "text", "required": true },
|
|
||||||
{ "key": "emergencia_telefono", "label": "form.emergencia_telefono", "type": "phone_country", "required": true, "source": "/forms/paises.json" },
|
|
||||||
{ "key": "emergencia_correo", "label": "form.emergencia_correo", "type": "email", "required": false }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "form.step8",
|
|
||||||
"column": 2,
|
|
||||||
"fields": [
|
|
||||||
{ "key": "confirmar_nombre", "label": "form.confirmar_nombre", "type": "text", "readonly": true, "valueFrom": "nombre_completo" },
|
|
||||||
{ "key": "confirmar_firma", "label": "form.confirmar_firma", "type": "text", "readonly": true, "valueFrom": "reglamento_firma" },
|
|
||||||
{
|
|
||||||
"key": "declaracion_voluntario",
|
|
||||||
"label": "form.declaracion_voluntario",
|
|
||||||
"type": "checkbox",
|
|
||||||
"required": true,
|
|
||||||
"colspan": 2,
|
|
||||||
"options": [
|
|
||||||
{ "value": "informacion_verdadera", "label": "form.declaracion.verdadera", "required": true },
|
|
||||||
{ "value": "acepto_reglamento", "label": "form.declaracion.acepto_reglamento", "required": true },
|
|
||||||
{ "value": "compromiso_etica", "label": "form.declaracion.compromiso_etica", "required": true },
|
|
||||||
{ "value": "autorizo_datos", "label": "form.declaracion.autorizo_datos", "required": true },
|
|
||||||
{ "value": "confidencialidad", "label": "form.declaracion.confidencialidad", "required": true },
|
|
||||||
{ "value": "participacion_voluntaria", "label": "form.declaracion.voluntaria", "required": true }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ "key": "confirmacion", "label": "form.confirmacion", "type": "checkbox", "colspan": 2, "required": true, "options": [
|
|
||||||
{ "value": "confirmado", "label": "form.confirmacion_label", "required": true }
|
|
||||||
] }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 405 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
|
@ -1,187 +0,0 @@
|
||||||
<h1>General Volunteer Program Regulations</h1>
|
|
||||||
<p>Volunteer Terms, Conditions, and Code of Conduct</p>
|
|
||||||
|
|
||||||
<section id="introduccion">
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
<p>The Kingdom of Peace and Justice Center’s mission is to promote peace, justice, leadership, education, humanitarian aid, social responsibility, and cooperation among communities and nations.</p>
|
|
||||||
<p>The following Regulations establish the legal, ethical, and institutional framework that governs the participation of volunteers, defining their rights, obligations, and principles of conduct, in order to ensure that all volunteer activities are carried out in accordance with the values of the Center and applicable law.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="objeto-voluntariado">
|
|
||||||
<h2>1. Purpose of the Volunteering</h2>
|
|
||||||
<p>The volunteer participates freely and voluntarily in the events of the Center for the purpose of contributing to the fulfillment of its institutional mission in the areas of education, community development, humanitarian assistance, leadership, public diplomacy, promotion of peace and justice, and service to society.</p>
|
|
||||||
<p>All activities shall be carried out with a spirit of service, responsibility, integrity, respect, cooperation, and commitment to the common good.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="naturaleza-voluntariado">
|
|
||||||
<h2>2. Nature of Volunteering</h2>
|
|
||||||
<p>The volunteer’s participation is exclusively voluntary in nature and does not constitute, under any circumstances, an employment, contractual, corporate, representative, agency, or subordinate relationship with the Center.</p>
|
|
||||||
<p>Participation in the events does not generate any right to salary, employment benefits, social security, compensation, or any other economic remuneration, except with the express written authorization of the Center regarding reimbursement of expenses.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="requisitos-voluntario">
|
|
||||||
<h2>3. Requirements to Become a Volunteer</h2>
|
|
||||||
<p>The volunteer declares that:</p>
|
|
||||||
<ul>
|
|
||||||
<li>The information provided is truthful, complete, and up to date.</li>
|
|
||||||
<li>They are physically and mentally fit to participate in the activities.</li>
|
|
||||||
<li>There is no legal incapacity or restriction to their participation.</li>
|
|
||||||
<li>They will comply with the policies, regulations, and procedures established by the Center.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="seguro">
|
|
||||||
<h2>4. Insurance Coverage</h2>
|
|
||||||
<p>Unless expressly communicated in writing by the Center, each volunteer shall be responsible for having the medical, accident, and other insurance coverage they deem necessary for their participation.</p>
|
|
||||||
<p>The purchase of any insurance by the Center does not replace the personal responsibility of the volunteer.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="responsabilidad-medica">
|
|
||||||
<h2>5. Medical Liability</h2>
|
|
||||||
<p>The volunteer states that their state of health allows them to participate in the events and agrees to promptly report any medical condition that may affect their safety or that of third parties.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normas">
|
|
||||||
<h2>6. Compliance with Rules</h2>
|
|
||||||
<p>The volunteer agrees to comply with the instructions given by Center representatives, respect safety rules, and to always act with responsibility, professionalism, and respect toward all persons.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="confidencialidad">
|
|
||||||
<h2>7. Confidentiality</h2>
|
|
||||||
<p>All information to which the volunteer has access during their participation shall be considered confidential.</p>
|
|
||||||
<p>The volunteer agrees not to disclose institutional, financial, strategic, personal, or any other reserved information, even after their collaboration with the Center has ended.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-datos">
|
|
||||||
<h2>8. Protection of Personal Data</h2>
|
|
||||||
<p>The volunteer authorizes the Center to collect, store, and process their personal data exclusively for purposes related to:</p>
|
|
||||||
<ul>
|
|
||||||
<li>the administration of the volunteer program;</li>
|
|
||||||
<li>institutional communication;</li>
|
|
||||||
<li>the organization of events;</li>
|
|
||||||
<li>compliance with legal obligations;</li>
|
|
||||||
<li>the safety of participants.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen">
|
|
||||||
<h2>9. Image Use</h2>
|
|
||||||
<p>The volunteer authorizes the Center to use photographs, audio recordings, videos, and images obtained during the events for institutional, educational, informational, promotional, and fundraising purposes, unless they expressly state otherwise in writing.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="propiedad-intelectual">
|
|
||||||
<h2>10. Intellectual Property</h2>
|
|
||||||
<p>Any document, photograph, video, audiovisual material, presentation, publication, content, or work developed by the volunteer within the institutional events will be the exclusive property of the Center, unless otherwise agreed in writing.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-bienes">
|
|
||||||
<h2>11. Property Use and Care</h2>
|
|
||||||
<p>The volunteer will use the Center’s property, equipment, and materials responsibly, agreeing to maintain them in good condition and return them when required or at the end of their participation.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="terminacion-voluntariado">
|
|
||||||
<h2>12. Termination of Volunteer Participation</h2>
|
|
||||||
<p>The Center may suspend or terminate the participation of any volunteer when there is noncompliance with these Regulations, conduct that is incompatible with institutional values, risks to the organization, or any other justified reason.</p>
|
|
||||||
<p>The volunteer may withdraw freely by providing reasonable advance notice.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="limitacion-responsabilidad">
|
|
||||||
<h2>13. Limitation of Liability</h2>
|
|
||||||
<p>The volunteer acknowledges that they participate freely in the Center’s activities and accept the normal risks inherent to them.</p>
|
|
||||||
<p>To the extent permitted by applicable law, the Center, its directors, employees, representatives, collaborators, and other volunteers will not be liable for damages arising from the volunteer’s participation, except in cases of willful misconduct or gross negligence.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="declaracion-riesgos">
|
|
||||||
<h2>14. Assumption of Risk Statement</h2>
|
|
||||||
<p>The volunteer declares that they are aware that certain events may involve risks arising from travel, community work, humanitarian assistance, public events, institutional visits, or other events of the program.</p>
|
|
||||||
<p>The volunteer accepts participation under their own responsibility and voluntarily assumes such risks, except when there is willful misconduct or gross negligence attributable to the Center.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conducta-institucional">
|
|
||||||
<h2>15. Institutional Conduct</h2>
|
|
||||||
<p>The volunteer agrees to maintain conduct consistent with the principles and values of the Center.</p>
|
|
||||||
<p>The following are prohibited:</p>
|
|
||||||
<ul>
|
|
||||||
<li>committing acts of physical or verbal violence;</li>
|
|
||||||
<li>discriminating against or harassing any person;</li>
|
|
||||||
<li>consuming illegal drugs or appearing under the influence;</li>
|
|
||||||
<li>carrying weapons without legal and express authorization;</li>
|
|
||||||
<li>requesting donations or administering financial resources on behalf of the Center without written authorization;</li>
|
|
||||||
<li>using the name of the Center for personal, political, or commercial purposes.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-menores">
|
|
||||||
<h2>16. Safeguarding Minors and Vulnerable Individuals</h2>
|
|
||||||
<p>When events involve minors or individuals in situations of vulnerability, the volunteer shall strictly comply with the protection protocols established by the Center and applicable law.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conflicto-intereses">
|
|
||||||
<h2>17. Conflict of Interest</h2>
|
|
||||||
<p>The volunteer shall report any personal, professional, economic, or family situation that could create a conflict of interest with the activities of the Center.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normativo">
|
|
||||||
<h2>18. Regulatory Compliance</h2>
|
|
||||||
<p>The volunteer agrees to comply with all applicable legislation related to human rights, protection of personal data, anti-corruption, prevention of money laundering, equality, nondiscrimination, and all other applicable rules.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen-institucional">
|
|
||||||
<h2>19. Use of the Institutional Name and Image</h2>
|
|
||||||
<p>The Center’s name, logo, trademarks, corporate image, and other distinctive signs may only be used with prior written authorization.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="redes-sociales">
|
|
||||||
<h2>20. Social Media and Communications</h2>
|
|
||||||
<p>The volunteer may not issue public statements, interviews, communications, or publications on behalf of the Center without prior authorization.</p>
|
|
||||||
<p>They also agree to use social media responsibly, avoiding publications that may affect the institutional image.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="donaciones">
|
|
||||||
<h2>21. Donations</h2>
|
|
||||||
<p>The status of volunteer does not grant any right over the goods, resources, projects, or donations administered by the Center.</p>
|
|
||||||
<p>Any fundraising campaign must have prior written authorization.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="fuerza-mayor">
|
|
||||||
<h2>22. Force Majeure</h2>
|
|
||||||
<p>The Center may suspend, modify, or cancel any event due to force majeure, security reasons, armed conflicts, health emergencies, natural disasters, or any other circumstance beyond its control, without this generating any liability.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="legislacion-jurisdiccion">
|
|
||||||
<h2>23. Applicable Law and Jurisdiction</h2>
|
|
||||||
<p>These Regulations shall be governed by the laws in force in the country where the volunteer events are carried out.</p>
|
|
||||||
<p>Any dispute shall be submitted to the jurisdiction of the competent courts of that country.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="codigo-etica">
|
|
||||||
<h2>Volunteer Code of Conduct</h2>
|
|
||||||
<p>Every volunteer commits to:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Act with honesty, integrity, and transparency.</li>
|
|
||||||
<li>Respect the dignity and rights of all people.</li>
|
|
||||||
<li>Promote a culture of peace, justice, and solidarity.</li>
|
|
||||||
<li>Maintain absolute confidentiality.</li>
|
|
||||||
<li>Avoid conflicts of interest.</li>
|
|
||||||
<li>Represent the Center with respect and professionalism.</li>
|
|
||||||
<li>Comply with applicable law and institutional policies.</li>
|
|
||||||
<li>Protect the reputation and values of the Center.</li>
|
|
||||||
<li>Always act with a spirit of service.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="politica-privacidad">
|
|
||||||
<h2>Data Protection and Privacy Policy</h2>
|
|
||||||
<p>The Center recognizes the importance of protecting the privacy of its volunteers and agrees to process all personal information in accordance with applicable law.</p>
|
|
||||||
<p>Personal data shall be used exclusively for:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Administration of the volunteer program.</li>
|
|
||||||
<li>Organization of activities and events.</li>
|
|
||||||
<li>Institutional communication.</li>
|
|
||||||
<li>Compliance with legal obligations.</li>
|
|
||||||
<li>Protection and safety of participants.</li>
|
|
||||||
<li>Preparation of statistics and institutional reports.</li>
|
|
||||||
</ul>
|
|
||||||
<p>The Center shall adopt reasonable technical, administrative, and organizational measures to protect personal information against loss, unauthorized access, alteration, disclosure, or improper use.</p>
|
|
||||||
<p>Volunteers may exercise the rights granted to them by applicable law regarding access, rectification, updating, or deletion of their personal data.</p>
|
|
||||||
</section>
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
<h1>Reglamento General del Programa de Voluntariado</h1>
|
|
||||||
<p>Términos, Condiciones y Código de Ética para Voluntarios</p>
|
|
||||||
|
|
||||||
<section id="introduccion">
|
|
||||||
<h2>Introducción</h2>
|
|
||||||
<p>El Centro del Reino de Paz y Justicia (CRPJ) tiene como misión promover la paz, la justicia, el liderazgo, la educación, la ayuda humanitaria, la responsabilidad social y la cooperación entre comunidades y naciones.</p>
|
|
||||||
<p>El presente Reglamento establece el marco jurídico, ético e institucional que regula la participación de los voluntarios, definiendo sus derechos, obligaciones y principios de actuación, con el fin de garantizar que todas las actividades de voluntariado se desarrollen conforme a los valores del CRPJ y a la legislación aplicable.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="objeto-voluntariado">
|
|
||||||
<h2>1. Objeto del Voluntariado</h2>
|
|
||||||
<p>El voluntario participa libre y participa libremente, por un deseo propio y personal, en las actividades del CRPJ con el propósito de contribuir al cumplimiento de la misión institucional en las áreas de educación, desarrollo comunitario, asistencia humanitaria, liderazgo, diplomacia pública, promoción de la paz, la justicia y el servicio a la sociedad.</p>
|
|
||||||
<p>Toda actividad deberá desarrollarse con espíritu de servicio, responsabilidad, integridad, respeto, cooperación y compromiso con el bienestar común.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="naturaleza-voluntariado">
|
|
||||||
<h2>2. Naturaleza del Voluntariado</h2>
|
|
||||||
<p>La labor de quien participa tiene carácter exclusivamente voluntario y no constituye, bajo ninguna circunstancia, una relación laboral, contractual, societaria, de representación, mandato o subordinación con el CRPJ.</p>
|
|
||||||
<p>La participación en las actividades no genera derecho a salario, prestaciones laborales, seguridad social, indemnizaciones ni cualquier otra remuneración económica, salvo autorización expresa y por escrito del CRPJ respecto del reembolso de gastos.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="requisitos-voluntario">
|
|
||||||
<h2>3. Requisitos para ser Voluntario</h2>
|
|
||||||
<p>El voluntario declara que:</p>
|
|
||||||
<ul>
|
|
||||||
<li>La información proporcionada por el voluntario es veraz, completa y actualizada.</li>
|
|
||||||
<li>Se encuentra física y mentalmente apto para participar en las actividades.</li>
|
|
||||||
<li>No existe impedimento legal para su participación.</li>
|
|
||||||
<li>Cumplirá las políticas, reglamentos y procedimientos establecidos por el CRPJ.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="seguro">
|
|
||||||
<h2>4. Seguro</h2>
|
|
||||||
<p>Salvo comunicación expresa y por escrito del CRPJ, cada voluntario será responsable de contar con la cobertura médica, de accidentes y demás seguros que considere necesarios para su participación.</p>
|
|
||||||
<p>La contratación de cualquier seguro por parte del CRPJ no sustituye la responsabilidad personal del voluntario.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="responsabilidad-medica">
|
|
||||||
<h2>5. Responsabilidad Médica</h2>
|
|
||||||
<p>El voluntario manifiesta que su estado de salud le permite participar en las actividades y se compromete a informar oportunamente cualquier condición médica que pueda afectar su seguridad o la de terceros.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normas">
|
|
||||||
<h2>6. Cumplimiento de Normas</h2>
|
|
||||||
<p>El voluntario se compromete a cumplir las instrucciones impartidas por los responsables del CRPJ, respetar las normas de seguridad y actuar siempre con responsabilidad, profesionalismo y respeto hacia todas las personas.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="confidencialidad">
|
|
||||||
<h2>7. Confidencialidad</h2>
|
|
||||||
<p>Toda la información a la que el voluntario tenga acceso durante su participación será considerada confidencial.</p>
|
|
||||||
<p>El voluntario se obliga a no divulgar información institucional, financiera, estratégica, personal o cualquier otra información reservada, aun después de finalizar su colaboración con el CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-datos">
|
|
||||||
<h2>8. Protección de Datos Personales</h2>
|
|
||||||
<p>El voluntario autoriza al CRPJ a recopilar, almacenar y tratar sus datos personales exclusivamente para fines relacionados con:</p>
|
|
||||||
<ul>
|
|
||||||
<li>la administración del programa de voluntariado;</li>
|
|
||||||
<li>la comunicación institucional;</li>
|
|
||||||
<li>la organización de actividades;</li>
|
|
||||||
<li>el cumplimiento de obligaciones legales;</li>
|
|
||||||
<li>la seguridad de los participantes.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen">
|
|
||||||
<h2>9. Uso de Imagen</h2>
|
|
||||||
<p>El voluntario autoriza al CRPJ a utilizar fotografías, grabaciones de audio, videos e imágenes obtenidas durante las actividades para fines institucionales, educativos, informativos, promocionales y de recaudación de fondos, salvo manifestación expresa y escrita en caso contrario.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="propiedad-intelectual">
|
|
||||||
<h2>10. Propiedad Intelectual</h2>
|
|
||||||
<p>Todo documento, fotografía, video, material audiovisual, presentación, publicación, contenido o trabajo desarrollado por el voluntario dentro de las actividades institucionales será propiedad exclusiva del CRPJ, salvo acuerdo escrito en caso contrario.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-bienes">
|
|
||||||
<h2>11. Uso y Cuidado de Bienes</h2>
|
|
||||||
<p>El voluntario deberá utilizar responsablemente los bienes, equipos y materiales del CRPJ, comprometiéndose a conservarlos y devolverlos cuando le sean requeridos o al finalizar su participación.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="terminacion-voluntariado">
|
|
||||||
<h2>12. Terminación del Voluntariado</h2>
|
|
||||||
<p>El CRPJ podrá suspender o finalizar la participación de cualquier voluntario cuando exista incumplimiento del presente Reglamento, conducta incompatible con los valores institucionales, riesgos para la organización o cualquier otra causa justificada.</p>
|
|
||||||
<p>El voluntario podrá retirarse libremente notificándolo con una anticipación razonable.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="limitacion-responsabilidad">
|
|
||||||
<h2>13. Limitación de Responsabilidad</h2>
|
|
||||||
<p>El voluntario reconoce que participa libremente en las actividades del CRPJ y acepta los riesgos normales inherentes a las mismas.</p>
|
|
||||||
<p>En la medida permitida por la legislación aplicable, el CRPJ, sus directivos, empleados, representantes, colaboradores y demás voluntarios no serán responsables por daños derivados de la participación del voluntario, salvo en casos de dolo o negligencia grave.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="declaracion-riesgos">
|
|
||||||
<h2>14. Declaración de Asunción de Riesgos</h2>
|
|
||||||
<p>El voluntario declara conocer que determinadas actividades pueden implicar riesgos derivados de desplazamientos, trabajo comunitario, asistencia humanitaria, eventos públicos, visitas institucionales u otras actividades propias del programa.</p>
|
|
||||||
<p>El voluntario acepta participar bajo su propia responsabilidad y asume voluntariamente dichos riesgos, salvo cuando exista dolo o negligencia grave imputable al CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conducta-institucional">
|
|
||||||
<h2>15. Conducta Institucional</h2>
|
|
||||||
<p>El voluntario se compromete a mantener una conducta acorde con los principios y valores del CRPJ.</p>
|
|
||||||
<p>Queda prohibido:</p>
|
|
||||||
<ul>
|
|
||||||
<li>realizar actos de violencia física o verbal;</li>
|
|
||||||
<li>discriminar o acosar a cualquier persona;</li>
|
|
||||||
<li>consumir drogas ilegales o presentarse bajo sus efectos;</li>
|
|
||||||
<li>portar armas sin autorización legal y expresa;</li>
|
|
||||||
<li>solicitar donaciones o administrar recursos económicos en nombre del CRPJ sin autorización escrita;</li>
|
|
||||||
<li>utilizar el nombre del CRPJ para fines personales, políticos o comerciales.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-menores">
|
|
||||||
<h2>16. Protección de Menores y Personas Vulnerables</h2>
|
|
||||||
<p>Cuando las actividades involucren menores de edad o personas en situación de vulnerabilidad, el voluntario deberá cumplir estrictamente los protocolos de protección establecidos por el CRPJ y la legislación aplicable.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conflicto-intereses">
|
|
||||||
<h2>17. Conflicto de Intereses</h2>
|
|
||||||
<p>El voluntario deberá informar cualquier situación personal, profesional, económica o familiar que pudiera generar un conflicto de interés con las actividades del CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normativo">
|
|
||||||
<h2>18. Cumplimiento Normativo</h2>
|
|
||||||
<p>El voluntario se compromete a cumplir toda la legislación aplicable relacionada con derechos humanos, protección de datos personales, anticorrupción, prevención del lavado de dinero, igualdad, no discriminación y demás normas aplicables.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen-institucional">
|
|
||||||
<h2>19. Uso del Nombre e Imagen Institucional</h2>
|
|
||||||
<p>El nombre, logotipo, marcas, imagen corporativa y demás signos distintivos del CRPJ únicamente podrán utilizarse con autorización previa y escrita.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="redes-sociales">
|
|
||||||
<h2>20. Redes Sociales y Comunicaciones</h2>
|
|
||||||
<p>El voluntario no podrá emitir declaraciones públicas, entrevistas, comunicados o publicaciones en representación del CRPJ sin autorización previa.</p>
|
|
||||||
<p>Asimismo, se compromete a utilizar responsablemente las redes sociales evitando publicaciones que puedan afectar la imagen institucional.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="donaciones">
|
|
||||||
<h2>21. Donaciones</h2>
|
|
||||||
<p>La condición de voluntario no otorga derecho alguno sobre los bienes, recursos, proyectos o donaciones administrados por el CRPJ.</p>
|
|
||||||
<p>Toda campaña de recaudación de fondos deberá contar con autorización previa y escrita.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="fuerza-mayor">
|
|
||||||
<h2>22. Fuerza Mayor</h2>
|
|
||||||
<p>El CRPJ podrá suspender, modificar o cancelar cualquier actividad debido a causas de fuerza mayor, razones de seguridad, conflictos armados, emergencias sanitarias, desastres naturales o cualquier otra circunstancia fuera de su control, sin que ello genere responsabilidad alguna.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="legislacion-jurisdiccion">
|
|
||||||
<h2>23. Legislación Aplicable y Jurisdicción</h2>
|
|
||||||
<p>El presente Reglamento se regirá por la legislación vigente del país donde se desarrollen las actividades del voluntariado.</p>
|
|
||||||
<p>Toda controversia será sometida a la jurisdicción de los tribunales competentes de dicho país.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="codigo-etica">
|
|
||||||
<h2>Código de Ética del Voluntario</h2>
|
|
||||||
<p>Todo voluntario se compromete a:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Actuar con honestidad, integridad y transparencia.</li>
|
|
||||||
<li>Respetar la dignidad y los derechos de todas las personas.</li>
|
|
||||||
<li>Promover una cultura de paz, justicia y solidaridad.</li>
|
|
||||||
<li>Mantener absoluta confidencialidad.</li>
|
|
||||||
<li>Evitar conflictos de interés.</li>
|
|
||||||
<li>Representar al CRPJ con respeto y profesionalismo.</li>
|
|
||||||
<li>Cumplir la legislación aplicable y las políticas institucionales.</li>
|
|
||||||
<li>Proteger la reputación y los valores del CRPJ.</li>
|
|
||||||
<li>Actuar siempre con espíritu de servicio.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="politica-privacidad">
|
|
||||||
<h2>Política de Privacidad y Tratamiento de Datos Personales</h2>
|
|
||||||
<p>El CRPJ reconoce la importancia de proteger la privacidad de sus voluntarios y se compromete a tratar toda información personal conforme a la legislación aplicable.</p>
|
|
||||||
<p>Los datos personales serán utilizados exclusivamente para:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Administración del programa de voluntariado.</li>
|
|
||||||
<li>Organización de actividades y eventos.</li>
|
|
||||||
<li>Comunicación institucional.</li>
|
|
||||||
<li>Cumplimiento de obligaciones legales.</li>
|
|
||||||
<li>Protección y seguridad de los participantes.</li>
|
|
||||||
<li>Elaboración de estadísticas e informes institucionales.</li>
|
|
||||||
</ul>
|
|
||||||
<p>El CRPJ adoptará medidas técnicas, administrativas y organizativas razonables para proteger la información personal contra pérdida, acceso no autorizado, alteración, divulgación o uso indebido.</p>
|
|
||||||
<p>Los voluntarios podrán ejercer los derechos que les otorgue la legislación aplicable respecto del acceso, rectificación, actualización o eliminación de sus datos personales.</p>
|
|
||||||
</section>
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
<h1>Regulamento Geral do Programa de Voluntariado</h1>
|
|
||||||
<p>Termos, Condições e Código de Ética para Voluntários</p>
|
|
||||||
|
|
||||||
<section id="introduccion">
|
|
||||||
<h2>Introdução</h2>
|
|
||||||
<p>O Centro do Reino de Paz e Justiça (CRPJ) tem como missão promover a paz, a justiça, a liderança, a educação, a ajuda humanitária, a responsabilidade social e a cooperação entre comunidades e nações.</p>
|
|
||||||
<p>O presente Regulamento estabelece o marco jurídico, ético e institucional que disciplina a participação dos voluntários, definindo seus direitos, deveres e princípios de atuação, com o objetivo de assegurar que todas as atividades de voluntariado sejam desenvolvidas em conformidade com os valores do CRPJ e com a legislação aplicável.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="objeto-voluntariado">
|
|
||||||
<h2>1. Objeto do Voluntariado</h2>
|
|
||||||
<p>O voluntário participa de forma livre, por desejo próprio e pessoal, das atividades do CRPJ com o propósito de contribuir para o cumprimento da missão institucional nas áreas de educação, desenvolvimento comunitário, assistência humanitária, liderança, diplomacia pública, promoção da paz, da justiça e serviço à sociedade.</p>
|
|
||||||
<p>Todas as atividades deverão ser desenvolvidas com espírito de serviço, responsabilidade, integridade, respeito, cooperação e compromisso com o bem comum.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="naturaleza-voluntariado">
|
|
||||||
<h2>2. Natureza do Voluntariado</h2>
|
|
||||||
<p>A participação do voluntário possui caráter exclusivamente voluntário e não constitui, em hipótese alguma, vínculo empregatício, contratual, societário, de representação, de mandato ou de subordinação com o CRPJ.</p>
|
|
||||||
<p>A participação nas atividades não gera direito a salário, benefícios trabalhistas, previdência social, indenizações nem qualquer outra forma de remuneração, salvo mediante autorização expressa e por escrito do CRPJ para reembolso de despesas.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="requisitos-voluntario">
|
|
||||||
<h2>3. Requisitos para ser Voluntário</h2>
|
|
||||||
<p>O voluntário declara que:</p>
|
|
||||||
<ul>
|
|
||||||
<li>As informações fornecidas são verdadeiras, completas e atualizadas.</li>
|
|
||||||
<li>Encontra-se física e mentalmente apto para participar das atividades.</li>
|
|
||||||
<li>Não possui qualquer impedimento legal para sua participação.</li>
|
|
||||||
<li>Cumprirá as políticas, os regulamentos e os procedimentos estabelecidos pelo CRPJ.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="seguro">
|
|
||||||
<h2>4. Seguro</h2>
|
|
||||||
<p>Salvo comunicação expressa e por escrito do CRPJ, cada voluntário será responsável por possuir cobertura médica, seguro contra acidentes e quaisquer outros seguros que considere necessários para sua participação.</p>
|
|
||||||
<p>A contratação de qualquer seguro pelo CRPJ não substitui a responsabilidade pessoal do voluntário.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="responsabilidad-medica">
|
|
||||||
<h2>5. Responsabilidade Médica</h2>
|
|
||||||
<p>O voluntário declara que seu estado de saúde lhe permite participar das atividades e compromete-se a informar prontamente qualquer condição médica que possa afetar sua segurança ou a de terceiros.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normas">
|
|
||||||
<h2>6. Cumprimento das Normas</h2>
|
|
||||||
<p>O voluntário compromete-se a cumprir as instruções dos responsáveis pelo CRPJ, respeitar as normas de segurança e atuar sempre com responsabilidade, profissionalismo e respeito para com todas as pessoas.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="confidencialidad">
|
|
||||||
<h2>7. Confidencialidade</h2>
|
|
||||||
<p>Todas as informações às quais o voluntário tiver acesso durante sua participação serão consideradas confidenciais.</p>
|
|
||||||
<p>O voluntário compromete-se a não divulgar informações institucionais, financeiras, estratégicas, pessoais ou quaisquer outras informações confidenciais, mesmo após o término de sua colaboração com o CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-dados">
|
|
||||||
<h2>8. Proteção de Dados Pessoais</h2>
|
|
||||||
<p>O voluntário autoriza o CRPJ a coletar, armazenar e tratar seus dados pessoais exclusivamente para as seguintes finalidades:</p>
|
|
||||||
<ul>
|
|
||||||
<li>administração do Programa de Voluntariado;</li>
|
|
||||||
<li>comunicação institucional;</li>
|
|
||||||
<li>organização de atividades;</li>
|
|
||||||
<li>cumprimento de obrigações legais;</li>
|
|
||||||
<li>segurança dos participantes.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen">
|
|
||||||
<h2>9. Uso de Imagem</h2>
|
|
||||||
<p>O voluntário autoriza o CRPJ a utilizar fotografias, gravações de áudio, vídeos e imagens obtidos durante as atividades para fins institucionais, educacionais, informativos, promocionais e de captação de recursos, salvo manifestação expressa e por escrito em sentido contrário.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="propiedad-intelectual">
|
|
||||||
<h2>10. Propriedade Intelectual</h2>
|
|
||||||
<p>Todo documento, fotografia, vídeo, material audiovisual, apresentação, publicação, conteúdo ou trabalho desenvolvido pelo voluntário no âmbito das atividades institucionais será de propriedade exclusiva do CRPJ, salvo acordo em contrário formalizado por escrito.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-bienes">
|
|
||||||
<h2>11. Uso e Conservação dos Bens</h2>
|
|
||||||
<p>O voluntário deverá utilizar os bens, equipamentos e materiais do CRPJ de forma responsável, comprometendo-se a conservá-los e devolvê-los sempre que solicitado ou ao término de sua participação.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="terminacion-voluntariado">
|
|
||||||
<h2>12. Encerramento do Voluntariado</h2>
|
|
||||||
<p>O CRPJ poderá suspender ou encerrar a participação de qualquer voluntário em caso de descumprimento do presente Regulamento, conduta incompatível com os valores institucionais, riscos para a organização ou qualquer outra causa devidamente justificada.</p>
|
|
||||||
<p>O voluntário poderá desligar-se do Programa a qualquer momento, mediante comunicação com antecedência razoável.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="limitacion-responsabilidad">
|
|
||||||
<h2>13. Limitação de Responsabilidade</h2>
|
|
||||||
<p>O voluntário reconhece que participa das atividades do CRPJ de forma livre e voluntária e aceita os riscos normais inerentes a elas.</p>
|
|
||||||
<p>Na medida permitida pela legislação aplicável, o CRPJ, seus dirigentes, empregados, representantes, colaboradores e demais voluntários não serão responsáveis por danos decorrentes da participação do voluntário, salvo nos casos de dolo ou culpa grave.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="declaracion-riesgos">
|
|
||||||
<h2>14. Declaração de Assunção de Riscos</h2>
|
|
||||||
<p>O voluntário declara estar ciente de que determinadas atividades podem envolver riscos decorrentes de deslocamentos, trabalho comunitário, assistência humanitária, eventos públicos, visitas institucionais ou outras atividades próprias do Programa.</p>
|
|
||||||
<p>O voluntário aceita participar sob sua própria responsabilidade e assume voluntariamente tais riscos, salvo quando houver dolo ou culpa grave imputável ao CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conducta-institucional">
|
|
||||||
<h2>15. Conduta Institucional</h2>
|
|
||||||
<p>O voluntário compromete-se a manter conduta compatível com os princípios e valores do CRPJ.</p>
|
|
||||||
<p>É proibido ao voluntário:</p>
|
|
||||||
<ul>
|
|
||||||
<li>praticar atos de violência física ou verbal;</li>
|
|
||||||
<li>discriminar ou assediar qualquer pessoa;</li>
|
|
||||||
<li>consumir drogas ilícitas ou apresentar-se sob seus efeitos;</li>
|
|
||||||
<li>portar armas sem autorização legal e expressa;</li>
|
|
||||||
<li>solicitar doações ou administrar recursos financeiros em nome do CRPJ sem autorização por escrito;</li>
|
|
||||||
<li>utilizar o nome do CRPJ para fins pessoais, políticos ou comerciais.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="proteccion-menores">
|
|
||||||
<h2>16. Proteção de Menores e Pessoas em Situação de Vulnerabilidade</h2>
|
|
||||||
<p>Quando as atividades envolverem menores de idade ou pessoas em situação de vulnerabilidade, o voluntário deverá cumprir rigorosamente os protocolos de proteção estabelecidos pelo CRPJ e a legislação aplicável.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="conflicto-intereses">
|
|
||||||
<h2>17. Conflito de Interesses</h2>
|
|
||||||
<p>O voluntário deverá comunicar qualquer situação de natureza pessoal, profissional, econômica ou familiar que possa gerar conflito de interesses em relação às atividades do CRPJ.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="cumplimiento-normativo">
|
|
||||||
<h2>18. Cumprimento Normativo</h2>
|
|
||||||
<p>O voluntário compromete-se a cumprir toda a legislação aplicável relacionada aos direitos humanos, à proteção de dados pessoais, ao combate à corrupção, à prevenção da lavagem de dinheiro, à igualdade, à não discriminação e às demais normas aplicáveis.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="uso-imagen-institucional">
|
|
||||||
<h2>19. Uso do Nome e da Identidade Institucional</h2>
|
|
||||||
<p>O nome, o logotipo, as marcas, a identidade institucional e os demais sinais distintivos do CRPJ somente poderão ser utilizados mediante autorização prévia e por escrito.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="redes-sociales">
|
|
||||||
<h2>20. Redes Sociais e Comunicações</h2>
|
|
||||||
<p>O voluntário não poderá conceder declarações públicas, entrevistas, comunicados ou realizar publicações em nome do CRPJ sem autorização prévia.</p>
|
|
||||||
<p>Da mesma forma, compromete-se a utilizar as redes sociais de forma responsável, evitando publicações que possam prejudicar a imagem institucional.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="donaciones">
|
|
||||||
<h2>21. Doações</h2>
|
|
||||||
<p>A condição de voluntário não confere qualquer direito sobre os bens, recursos, projetos ou doações administrados pelo CRPJ.</p>
|
|
||||||
<p>Toda campanha de captação de recursos deverá ser previamente autorizada por escrito.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="fuerza-mayor">
|
|
||||||
<h2>22. Caso Fortuito ou Força Maior</h2>
|
|
||||||
<p>O CRPJ poderá suspender, alterar ou cancelar qualquer atividade em razão de caso fortuito ou força maior, motivos de segurança, conflitos armados, emergências sanitárias, desastres naturais ou quaisquer outras circunstâncias alheias ao seu controle, sem que isso gere qualquer responsabilidade.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="legislacion-jurisdiccion">
|
|
||||||
<h2>23. Legislação Aplicável e Jurisdição</h2>
|
|
||||||
<p>O presente Regulamento será regido pela legislação vigente do país onde forem desenvolvidas as atividades de voluntariado.</p>
|
|
||||||
<p>Qualquer controvérsia será submetida à jurisdição dos tribunais competentes desse país.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="codigo-etica">
|
|
||||||
<h2>Código de Ética do Voluntário</h2>
|
|
||||||
<p>Todo voluntário compromete-se a:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Atuar com honestidade, integridade e transparência.</li>
|
|
||||||
<li>Respeitar a dignidade e os direitos de todas as pessoas.</li>
|
|
||||||
<li>Promover uma cultura de paz, justiça e solidariedade.</li>
|
|
||||||
<li>Manter absoluto sigilo.</li>
|
|
||||||
<li>Evitar conflitos de interesses.</li>
|
|
||||||
<li>Representar o CRPJ com respeito e profissionalismo.</li>
|
|
||||||
<li>Cumprir a legislação aplicável e as políticas institucionais.</li>
|
|
||||||
<li>Preservar a reputação e os valores do CRPJ.</li>
|
|
||||||
<li>Atuar sempre com espírito de serviço.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="politica-privacidad">
|
|
||||||
<h2>Política de Privacidade e Tratamento de Dados Pessoais</h2>
|
|
||||||
<p>O CRPJ reconhece a importância de proteger a privacidade de seus voluntários e compromete-se a tratar todas as informações pessoais em conformidade com a legislação aplicável.</p>
|
|
||||||
<p>Os dados pessoais serão utilizados exclusivamente para:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Administração do Programa de Voluntariado;</li>
|
|
||||||
<li>Organização de atividades e eventos;</li>
|
|
||||||
<li>Comunicação institucional;</li>
|
|
||||||
<li>Cumprimento de obrigações legais;</li>
|
|
||||||
<li>Proteção e segurança dos participantes;</li>
|
|
||||||
<li>Elaboração de estatísticas e relatórios institucionais.</li>
|
|
||||||
</ul>
|
|
||||||
<p>O CRPJ adotará medidas técnicas, administrativas e organizacionais razoáveis para proteger as informações pessoais contra perda, acesso não autorizado, alteração, divulgação ou uso indevido.</p>
|
|
||||||
<p>Os voluntários poderão exercer os direitos assegurados pela legislação aplicável em relação ao acesso, à retificação, à atualização ou à exclusão de seus dados pessoais.</p>
|
|
||||||
</section>
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
{
|
|
||||||
"name": "📊 Reporte de Traducciones - cdrdpyj",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"id": "webhook-1",
|
|
||||||
"name": "Webhook",
|
|
||||||
"type": "n8n-nodes-base.webhook",
|
|
||||||
"typeVersion": 1.2,
|
|
||||||
"position": [250, 300],
|
|
||||||
"parameters": {
|
|
||||||
"path": "news-summary",
|
|
||||||
"httpMethod": "POST",
|
|
||||||
"authentication": "headerAuth",
|
|
||||||
"responseMode": "onReceived",
|
|
||||||
"responseData": "{{ $json }}",
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
"credentials": {
|
|
||||||
"httpHeaderAuth": {
|
|
||||||
"id": null,
|
|
||||||
"name": "crpj-summary-key"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "code-1",
|
|
||||||
"name": "Formatear datos",
|
|
||||||
"type": "n8n-nodes-base.code",
|
|
||||||
"typeVersion": 2,
|
|
||||||
"position": [480, 300],
|
|
||||||
"parameters": {
|
|
||||||
"language": "javaScript",
|
|
||||||
"code": "const langNames = {\n es: 'Español',\n en: 'English',\n fr: 'Français',\n pt: 'Português',\n rw: 'Kinyarwanda',\n he: 'עברית',\n uk: 'Українська',\n ru: 'Русский',\n kr: 'Kreyòl',\n};\n\nconst ORDER = ['es', 'en', 'fr', 'pt', 'rw', 'he', 'uk', 'ru', 'kr'];\nconst payload = $input.first().json.body;\n\nconst summaryRows = [];\nfor (const code of ORDER) {\n const s = payload.summary[code];\n if (!s) continue;\n summaryRows.push({\n json: {\n language: langNames[code] || code,\n code,\n totalEs: payload.totals.spanishArticles,\n translated: s.translated,\n missing: s.missing,\n percent: s.percent,\n },\n });\n}\n\nconst detailRows = [];\nconst orphanCount = payload.orphaned?.length || 0;\n\nif (orphanCount > 0) {\n const warnRow = { json: { date: '', spanishTitle: `⚠️ ${orphanCount} archivo(s) huérfano(s) — sin versión en español`, spanishUrl: '' } };\n for (const lang of ORDER) warnRow.json[lang] = '';\n detailRows.push(warnRow);\n}\n\nfor (const art of payload.articles) {\n const row = { json: { date: art.date, spanishTitle: art.spanishTitle, spanishUrl: art.spanishUrl || '' } };\n for (const lang of ORDER) row.json[lang] = art.files[lang] ? '✅' : '❌';\n detailRows.push(row);\n}\n\nfor (const orphan of payload.orphaned) {\n const row = { json: { date: orphan.groupId, spanishTitle: `⚠️ Huérfano: solo en ${orphan.languages.join(', ')}`, spanishUrl: orphan.urls?.[orphan.languages[0]] || '' } };\n for (const lang of ORDER) row.json[lang] = orphan.languages.includes(lang) ? '⚠️' : '—';\n detailRows.push(row);\n}\n\nreturn [summaryRows, detailRows];\n",
|
|
||||||
"mode": "raw"
|
|
||||||
},
|
|
||||||
"nodesOnOutput": {
|
|
||||||
"main": [
|
|
||||||
{
|
|
||||||
"type": "n8n-nodes-base.googleSheets",
|
|
||||||
"index": [
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "n8n-nodes-base.googleSheets",
|
|
||||||
"index": [
|
|
||||||
1
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sheets-summary",
|
|
||||||
"name": "Sheets - Resumen",
|
|
||||||
"type": "n8n-nodes-base.googleSheets",
|
|
||||||
"typeVersion": 4,
|
|
||||||
"position": [720, 180],
|
|
||||||
"parameters": {
|
|
||||||
"operation": "append",
|
|
||||||
"documentId": {
|
|
||||||
"__rl": true,
|
|
||||||
"value": "",
|
|
||||||
"mode": "id"
|
|
||||||
},
|
|
||||||
"sheetName": "Resumen",
|
|
||||||
"columns": {
|
|
||||||
"mappingMode": "defineBelow",
|
|
||||||
"value": {
|
|
||||||
"A": "={{ $json.language }}",
|
|
||||||
"B": "={{ $json.code }}",
|
|
||||||
"C": "={{ $json.totalEs }}",
|
|
||||||
"D": "={{ $json.translated }}",
|
|
||||||
"E": "={{ $json.missing }}",
|
|
||||||
"F": "={{ $json.percent }}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"options": {
|
|
||||||
"cellFormat": "USER_ENTERED",
|
|
||||||
"dataLocationOnSheet": "A:F"
|
|
||||||
},
|
|
||||||
"handshake": false
|
|
||||||
},
|
|
||||||
"credentials": {
|
|
||||||
"googleSheetsOAuth2Api": {
|
|
||||||
"id": null,
|
|
||||||
"name": "Google Sheets"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sheets-detail",
|
|
||||||
"name": "Sheets - Detalle",
|
|
||||||
"type": "n8n-nodes-base.googleSheets",
|
|
||||||
"typeVersion": 4,
|
|
||||||
"position": [720, 420],
|
|
||||||
"parameters": {
|
|
||||||
"operation": "append",
|
|
||||||
"documentId": {
|
|
||||||
"__rl": true,
|
|
||||||
"value": "",
|
|
||||||
"mode": "id"
|
|
||||||
},
|
|
||||||
"sheetName": "Detalle",
|
|
||||||
"columns": {
|
|
||||||
"mappingMode": "defineBelow",
|
|
||||||
"value": {
|
|
||||||
"A": "={{ $json.date }}",
|
|
||||||
"B": "={{ $json.spanishTitle }}",
|
|
||||||
"C": "={{ $json.spanishUrl }}",
|
|
||||||
"D": "={{ $json.es }}",
|
|
||||||
"E": "={{ $json.en }}",
|
|
||||||
"F": "={{ $json.fr }}",
|
|
||||||
"G": "={{ $json.pt }}",
|
|
||||||
"H": "={{ $json.rw }}",
|
|
||||||
"I": "={{ $json.he }}",
|
|
||||||
"J": "={{ $json.uk }}",
|
|
||||||
"K": "={{ $json.ru }}",
|
|
||||||
"L": "={{ $json.kr }}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"options": {
|
|
||||||
"cellFormat": "USER_ENTERED",
|
|
||||||
"dataLocationOnSheet": "A:L"
|
|
||||||
},
|
|
||||||
"handshake": false
|
|
||||||
},
|
|
||||||
"credentials": {
|
|
||||||
"googleSheetsOAuth2Api": {
|
|
||||||
"id": null,
|
|
||||||
"name": "Google Sheets"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"connections": {
|
|
||||||
"Webhook": {
|
|
||||||
"main": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"node": "Formatear datos",
|
|
||||||
"type": "main",
|
|
||||||
"index": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Formatear datos": {
|
|
||||||
"main": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"node": "Sheets - Resumen",
|
|
||||||
"type": "main",
|
|
||||||
"index": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"node": "Sheets - Detalle",
|
|
||||||
"type": "main",
|
|
||||||
"index": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"active": false,
|
|
||||||
"settings": {},
|
|
||||||
"staticData": null,
|
|
||||||
"tags": [],
|
|
||||||
"versionId": "1.0"
|
|
||||||
}
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
||||||
import '@dotenvx/dotenvx/config';
|
|
||||||
import { readFileSync, readdirSync, existsSync } from 'fs';
|
|
||||||
import { join, dirname } from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import { google } from 'googleapis';
|
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
const ROOT = join(__dirname, '..');
|
|
||||||
const NEWS_DIR = join(ROOT, 'src', 'content', 'news');
|
|
||||||
const LANGUAGES = ['es', 'en', 'fr', 'pt', 'rw', 'he', 'uk', 'ru', 'kr'];
|
|
||||||
|
|
||||||
function extractField(fm, field) {
|
|
||||||
const re = new RegExp(`^${field}:\\s*(.*)$`, 'm');
|
|
||||||
const m = fm.match(re);
|
|
||||||
if (!m) return '';
|
|
||||||
let val = m[1].trim();
|
|
||||||
if ((val.startsWith("'") && val.endsWith("'")) ||
|
|
||||||
(val.startsWith('"') && val.endsWith('"'))) {
|
|
||||||
val = val.slice(1, -1);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ROUTE_TRANSLATIONS = {
|
|
||||||
es: "noticias", en: "news", fr: "informations",
|
|
||||||
he: "\u05d7\u05d3\u05e9\u05d5\u05ea", uk: "noticias", pt: "noticias",
|
|
||||||
ru: "\u043d\u043e\u0432\u043e\u0441\u0442\u0438", rw: "amakuru", kr: "nouvel",
|
|
||||||
};
|
|
||||||
|
|
||||||
function articleUrl(locale, slug) {
|
|
||||||
const route = ROUTE_TRANSLATIONS[locale] || 'news';
|
|
||||||
return `https://www.centrodelreinodepazyjusticia.com/${locale}/${route}/${slug}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function clearSheet(sheetName) {
|
|
||||||
const saEmail = process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL;
|
|
||||||
const pk = process.env.GOOGLE_PRIVATE_KEY;
|
|
||||||
const sid = process.env.GOOGLE_SHEET_ID;
|
|
||||||
if (!saEmail || !pk || !sid) {
|
|
||||||
console.log(`[send-to-n8n] Skipping sheet clear — missing Google credentials`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auth = new google.auth.GoogleAuth({
|
|
||||||
credentials: {
|
|
||||||
client_email: saEmail,
|
|
||||||
private_key: pk.replace(/\\n/g, '\n'),
|
|
||||||
},
|
|
||||||
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
|
|
||||||
});
|
|
||||||
const sheets = google.sheets({ version: 'v4', auth });
|
|
||||||
await sheets.spreadsheets.values.clear({
|
|
||||||
spreadsheetId: sid,
|
|
||||||
range: `${sheetName}!A:Z`,
|
|
||||||
});
|
|
||||||
console.log(`[send-to-n8n] Cleared sheet: ${sheetName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseMeta(filePath) {
|
|
||||||
const raw = readFileSync(filePath, 'utf-8');
|
|
||||||
const m = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
||||||
if (!m) return {};
|
|
||||||
const fm = m[1];
|
|
||||||
return {
|
|
||||||
locale: extractField(fm, 'locale'),
|
|
||||||
title: extractField(fm, 'title'),
|
|
||||||
date: extractField(fm, 'date'),
|
|
||||||
draft: extractField(fm, 'draft'),
|
|
||||||
slug: extractField(fm, 'slug'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function normFilename(fileName) {
|
|
||||||
const name = fileName.replace(/\.md$/, '');
|
|
||||||
return name.replace(/^(\d{4}-\d{2}-\d{2})-0(\d)$/, '$1-$2');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const groups = {};
|
|
||||||
|
|
||||||
for (const lang of LANGUAGES) {
|
|
||||||
const dir = join(NEWS_DIR, lang);
|
|
||||||
if (!existsSync(dir)) continue;
|
|
||||||
|
|
||||||
for (const file of readdirSync(dir).filter(f => f.endsWith('.md'))) {
|
|
||||||
const meta = parseMeta(join(dir, file));
|
|
||||||
if (meta.draft === 'true') continue;
|
|
||||||
|
|
||||||
const key = normFilename(file);
|
|
||||||
if (!groups[key]) groups[key] = {};
|
|
||||||
groups[key][lang] = {
|
|
||||||
file,
|
|
||||||
title: meta.title || '',
|
|
||||||
date: meta.date || '',
|
|
||||||
slug: meta.slug || '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const allKeys = Object.keys(groups).sort();
|
|
||||||
const esKeys = allKeys.filter(k => groups[k].es);
|
|
||||||
|
|
||||||
const summary = Object.fromEntries(LANGUAGES.map(l => {
|
|
||||||
const matches = esKeys.filter(k => groups[k][l]).length;
|
|
||||||
return [l, {
|
|
||||||
total: allKeys.filter(k => groups[k][l]).length,
|
|
||||||
translated: matches,
|
|
||||||
missing: esKeys.length - matches,
|
|
||||||
percent: esKeys.length > 0 ? Math.round((matches / esKeys.length) * 100) : 0,
|
|
||||||
}];
|
|
||||||
}));
|
|
||||||
|
|
||||||
const articles = esKeys.map(k => {
|
|
||||||
const es = groups[k].es;
|
|
||||||
const files = Object.fromEntries(LANGUAGES.map(l => [l, groups[k][l]?.file || null]));
|
|
||||||
const slugs = Object.fromEntries(LANGUAGES.map(l => [l, groups[k][l]?.slug || null]));
|
|
||||||
const urls = Object.fromEntries(LANGUAGES.map(l => {
|
|
||||||
const entry = groups[k][l];
|
|
||||||
return [l, entry?.slug ? articleUrl(l, entry.slug) : null];
|
|
||||||
}));
|
|
||||||
return {
|
|
||||||
groupId: k,
|
|
||||||
date: es?.date || '',
|
|
||||||
spanishTitle: es?.title || '',
|
|
||||||
spanishFile: es?.file || '',
|
|
||||||
spanishSlug: es?.slug || '',
|
|
||||||
spanishUrl: es?.slug ? articleUrl('es', es.slug) : '',
|
|
||||||
files,
|
|
||||||
slugs,
|
|
||||||
urls,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const orphaned = allKeys.filter(k => !groups[k].es).map(k => {
|
|
||||||
const langs = Object.keys(groups[k]);
|
|
||||||
const files = Object.fromEntries(langs.map(l => [l, groups[k][l].file]));
|
|
||||||
const slugs = Object.fromEntries(langs.map(l => [l, groups[k][l].slug]));
|
|
||||||
const urls = Object.fromEntries(langs.map(l => {
|
|
||||||
const entry = groups[k][l];
|
|
||||||
return [l, entry?.slug ? articleUrl(l, entry.slug) : null];
|
|
||||||
}));
|
|
||||||
return {
|
|
||||||
groupId: k,
|
|
||||||
languages: langs,
|
|
||||||
files,
|
|
||||||
slugs,
|
|
||||||
urls,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const payload = {
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
source: 'cdrdpyj-postbuild',
|
|
||||||
site: 'centrodelreinodepazyjusticia.com',
|
|
||||||
summary,
|
|
||||||
articles,
|
|
||||||
orphaned,
|
|
||||||
totals: {
|
|
||||||
spanishArticles: esKeys.length,
|
|
||||||
totalGroups: allKeys.length,
|
|
||||||
orphanedArticles: orphaned.length,
|
|
||||||
languages: Object.fromEntries(LANGUAGES.map(l => {
|
|
||||||
const c = allKeys.filter(k => groups[k][l]).length;
|
|
||||||
return [l, c];
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const orphanCount = orphaned.length;
|
|
||||||
if (orphanCount > 0) {
|
|
||||||
console.log(`[send-to-n8n] ⚠️ ${orphanCount} orphaned article(s) — missing Spanish version`);
|
|
||||||
orphaned.forEach(o => {
|
|
||||||
console.log(` ⚠️ ${o.groupId} solo en: ${o.languages.join(', ')}`);
|
|
||||||
Object.entries(o.urls).forEach(([l, u]) => console.log(` ${l}: ${u}`));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = process.env.N8N_WEBHOOK_URL;
|
|
||||||
if (!url) {
|
|
||||||
console.log('[send-to-n8n] N8N_WEBHOOK_URL not set — showing sample payload');
|
|
||||||
console.log('Summary:', JSON.stringify(payload.summary, null, 2));
|
|
||||||
console.log('Sample articles (first 5):');
|
|
||||||
payload.articles.slice(0, 5).forEach(a => {
|
|
||||||
console.log(` ${a.groupId} | ${a.date} | ${a.spanishTitle.slice(0, 60)}...`);
|
|
||||||
console.log(` → ES: ${a.spanishUrl}`);
|
|
||||||
const langs = Object.entries(a.urls).filter(([_, v]) => v).map(([k]) => k).join(', ');
|
|
||||||
console.log(` → Present in: ${langs || 'ES only'}`);
|
|
||||||
});
|
|
||||||
if (orphanCount) {
|
|
||||||
console.log('Orphaned articles:');
|
|
||||||
payload.orphaned.forEach(o => {
|
|
||||||
console.log(` ${o.groupId}`);
|
|
||||||
Object.entries(o.urls).forEach(([l, u]) => console.log(` ${l}: ${u}`));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
console.log(`[send-to-n8n] Total: ${articles.length} ES articles, ${orphanCount} orphans`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL && process.env.GOOGLE_SHEET_ID) {
|
|
||||||
try {
|
|
||||||
await clearSheet('Resumen');
|
|
||||||
await clearSheet('Detalle');
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`[send-to-n8n] Warning: could not clear sheets (${e.message})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiKey = process.env.N8N_API_KEY;
|
|
||||||
const apiKeyHeader = process.env.N8N_API_KEY_HEADER || 'X-API-Key';
|
|
||||||
const headers = { 'Content-Type': 'application/json' };
|
|
||||||
if (apiKey) headers[apiKeyHeader] = apiKey;
|
|
||||||
|
|
||||||
fetch(url, {
|
|
||||||
method: 'POST',
|
|
||||||
headers,
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
})
|
|
||||||
.then(r => {
|
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status} ${r.statusText}`);
|
|
||||||
console.log(`[send-to-n8n] OK — ${articles.length} ES articles, ${orphanCount} orphans`);
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.error(`[send-to-n8n] Warning: n8n unreachable (${e.message}) — build continues`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => {
|
|
||||||
console.error(`[send-to-n8n] Fatal error: ${e.message}`);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
Before Width: | Height: | Size: 405 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 189 KiB |
|
|
@ -1,18 +1,9 @@
|
||||||
---
|
---
|
||||||
import { ClientRouter } from "astro:transitions";
|
import { ClientRouter } from "astro:transitions";
|
||||||
|
|
||||||
import { GoogleAnalytics } from "astro-google-analytics";
|
import { GoogleAnalytics } from 'astro-google-analytics';
|
||||||
const {
|
const { title = "Centro del Reino de Paz y Justicia", description = "" } =
|
||||||
title = "Centro del Reino de Paz y Justicia",
|
Astro.props;
|
||||||
description = "",
|
|
||||||
image = null,
|
|
||||||
url = null,
|
|
||||||
date = null,
|
|
||||||
noindex = false,
|
|
||||||
} = Astro.props;
|
|
||||||
|
|
||||||
const imageUrl = image ? new URL(image, Astro.site).toString() : null;
|
|
||||||
const canonicalURL = new URL(url || Astro.url.pathname, Astro.site);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
|
@ -21,48 +12,8 @@ const canonicalURL = new URL(url || Astro.url.pathname, Astro.site);
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
{noindex && <meta name="robots" content="noindex, nofollow" />}
|
<GoogleAnalytics id="G-26KM3HWW9J" />
|
||||||
<GoogleAnalytics id="G-26KM3HWW9J" />
|
|
||||||
|
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<meta property="og:site_name" content={title} />
|
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
|
|
||||||
<!-- Open Graph -->
|
|
||||||
|
|
||||||
{url && <meta property="og:url" content={url} />}
|
|
||||||
<meta property="og:type" content="article" />
|
|
||||||
<meta property="og:title" content={title} />
|
|
||||||
<meta property="og:description" content={description} />
|
|
||||||
<link rel="canonical" href={canonicalURL} />
|
|
||||||
<meta name="telegram:channel" content="@CentroRPJ" />
|
|
||||||
|
|
||||||
{imageUrl && <meta property="og:image" content={imageUrl} />}
|
|
||||||
<meta property="og:image:width" content="1200" />
|
|
||||||
<meta property="og:image:height" content="630" />
|
|
||||||
|
|
||||||
{
|
|
||||||
date && (
|
|
||||||
<meta
|
|
||||||
property="article:published_time"
|
|
||||||
content={
|
|
||||||
date instanceof Date
|
|
||||||
? `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(
|
|
||||||
2,
|
|
||||||
"0"
|
|
||||||
)}-${String(date.getDate()).padStart(2, "0")}`
|
|
||||||
: date
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<!-- Twitter -->
|
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:title" content={title} />
|
|
||||||
<meta name="twitter:description" content={description} />
|
|
||||||
{imageUrl && <meta name="twitter:image" content={imageUrl} />}
|
|
||||||
{url && <meta name="twitter:url" content={url} />}
|
|
||||||
</head>
|
</head>
|
||||||
<ClientRouter />
|
<ClientRouter />
|
||||||
|
|
@ -2,10 +2,9 @@
|
||||||
const { props } = Astro.props;
|
const { props } = Astro.props;
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import Button from "./ui/Button.astro";
|
import Button from "./ui/Button.astro";
|
||||||
import { getLocalizedRoute } from '@/i18n';
|
import RegisterModal from "../components/RegisterModal.vue";
|
||||||
|
|
||||||
const background = props.bgImage || props.bgColor;
|
const background = props.bgImage || props.bgColor;
|
||||||
const formUrl = `/${Astro.currentLocale}/${getLocalizedRoute("formulario", Astro.currentLocale)}`;
|
|
||||||
|
|
||||||
---
|
---
|
||||||
<div style={{ background: props.bgImage ? `url('${props.bgImage}') center no-repeat; background-size:contain;` : props.bgColor }} class={`aspect-auto xl:aspect-square py-8 px-8 xl:px-16 flex flex-col justify-evenl`}>
|
<div style={{ background: props.bgImage ? `url('${props.bgImage}') center no-repeat; background-size:contain;` : props.bgColor }} class={`aspect-auto xl:aspect-square py-8 px-8 xl:px-16 flex flex-col justify-evenl`}>
|
||||||
|
|
@ -29,7 +28,7 @@ const formUrl = `/${Astro.currentLocale}/${getLocalizedRoute("formulario", Astro
|
||||||
|
|
||||||
{props.hasInput && (
|
{props.hasInput && (
|
||||||
<div class="flex gap-2 w-full mt-5">
|
<div class="flex gap-2 w-full mt-5">
|
||||||
<Button class="px-6 py-3 uppercase bg-[#22523F]" url={formUrl} variant="secondary" title={props.buttonLabel} />
|
<RegisterModal client:load locale={Astro.currentLocale} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,255 +2,75 @@
|
||||||
import Button from "./ui/Button.astro";
|
import Button from "./ui/Button.astro";
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
|
|
||||||
import { getCollection } from "astro:content";
|
import { createTranslator } from "../i18n/index.ts";
|
||||||
import { createTranslator, routeTranslations } from "../i18n/index.ts";
|
|
||||||
|
|
||||||
const allNews = await getCollection("news");
|
|
||||||
const allEditorial = await getCollection("editorial");
|
|
||||||
|
|
||||||
const tl = createTranslator(Astro.currentLocale);
|
const tl = createTranslator(Astro.currentLocale);
|
||||||
const currentLocale = Astro.currentLocale;
|
const currentLocale = Astro.currentLocale;
|
||||||
const currentPath = Astro.url.pathname;
|
|
||||||
const { locale } = Astro.params;
|
const { locale } = Astro.params;
|
||||||
const isAdmin = currentPath.split("/").includes("admin");
|
|
||||||
|
|
||||||
const languages = [
|
|
||||||
{ code: "es", icon: "icon_flag_es", label: "Español" },
|
|
||||||
{ code: "en", icon: "icon_flag_uk", label: "English" },
|
|
||||||
{ code: "he", icon: "flagpack--il", label: "עברית" },
|
|
||||||
{ code: "pt", icon: "flagpack--br", label: "Português" },
|
|
||||||
{ code: "fr", icon: "flagpack--fr", label: "Français" },
|
|
||||||
{ code: "ru", icon: "flagpack--ru", label: "Русский" },
|
|
||||||
{ code: "rw", icon: "flagpack--rw", label: "Kinyarwanda" },
|
|
||||||
{ code: "kr", icon: "flagpack--ht", label: "Kreole" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const navItems = [
|
|
||||||
{ href: "#somos", key: "nav.about" },
|
|
||||||
{ href: "#programs", key: "nav.programs" },
|
|
||||||
{ href: "#news", key: "nav.news" },
|
|
||||||
{ href: "#editorial", key: "nav.editorial" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const sidebarNavItems = [
|
|
||||||
{ href: `/`, key: "nav.home" },
|
|
||||||
{ href: "#somos", key: "nav.about" },
|
|
||||||
{ href: "#programs", key: "nav.programs" },
|
|
||||||
{ href: "#news", key: "nav.news" },
|
|
||||||
{ href: "#editorial", key: "nav.editorial" },
|
|
||||||
];
|
|
||||||
|
|
||||||
function translatePath(newLocale: string) {
|
|
||||||
const segments = currentPath.split("/").filter(Boolean);
|
|
||||||
if (segments.length === 0) return `/${newLocale}`;
|
|
||||||
const remainingSegments = segments.slice(1);
|
|
||||||
const allRouteNames = Object.values(routeTranslations).flatMap(r => Object.values(r));
|
|
||||||
const translatedSegments = remainingSegments.map((segment) => {
|
|
||||||
for (const key in routeTranslations) {
|
|
||||||
const translations =
|
|
||||||
routeTranslations[key as keyof typeof routeTranslations];
|
|
||||||
if (Object.values(translations).includes(segment)) {
|
|
||||||
return (
|
|
||||||
translations[newLocale as keyof typeof translations] ||
|
|
||||||
segment
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return segment;
|
|
||||||
});
|
|
||||||
if (segments.length >= 2 && allRouteNames.includes(segments[1])) {
|
|
||||||
if (segments.length >= 3) {
|
|
||||||
const currentId = segments[segments.length - 1];
|
|
||||||
const baseId = currentId.split("/").pop();
|
|
||||||
const existsInNews = allNews.some(
|
|
||||||
(post) =>
|
|
||||||
post.data.slug === baseId && post.data.locale === newLocale,
|
|
||||||
);
|
|
||||||
const existsInEditorial = allEditorial.some(
|
|
||||||
(post) =>
|
|
||||||
post.data.slug === baseId && post.data.locale === newLocale,
|
|
||||||
);
|
|
||||||
if (!existsInNews && !existsInEditorial) return `/${newLocale}/${translatedSegments[0]}`;
|
|
||||||
return `/${newLocale}/${translatedSegments[0]}/${baseId}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return `/${[newLocale, ...translatedSegments].join("/")}`;
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between px-8 md:px-0 md:py-4">
|
<div class="flex justify-between px-8 md:px-0 md:py-4">
|
||||||
<div class="border-l-4 border-colorPrimary pl-4">
|
<div class="border-l-4 border-colorPrimary pl-4">
|
||||||
<p
|
<p class="font-secondary text-colorPrimary font-bold leading-none py-2 text-2xl md:text-lg">
|
||||||
class="font-secondary text-colorPrimary font-bold leading-none py-2 text-2xl md:text-lg"
|
<a href={`/${currentLocale}`}>{tl("nav.logo_line1")}<br/>{tl("nav.logo_line2")}</a>
|
||||||
>
|
</p>
|
||||||
<a href={`/${currentLocale}`}
|
|
||||||
>{tl("nav.logo_line1")}<br />{tl("nav.logo_line2")}</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<nav
|
|
||||||
class="flex justify-end md:justify-evenly gap-4 md:gap-6 lg:gap-10 items-center uppercase text-md text-white"
|
|
||||||
>
|
|
||||||
<div class="hidden md:flex gap-4 lg:gap-8 font-primary font-bold">
|
|
||||||
{
|
|
||||||
navItems.map((item) => (
|
|
||||||
<a
|
|
||||||
class="hover:text-colorPrimary transition"
|
|
||||||
href={`/${currentLocale}${item.href}`}
|
|
||||||
>
|
|
||||||
{tl(item.key)}
|
|
||||||
</a>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
<!-- <a class="hover:text-colorPrimary transition" href={`/${currentLocale}/archive`}>{tl("nav.archive")}</a>
|
|
||||||
<a class="hover:text-colorPrimary transition" href={`/${currentLocale}/nations`}>{tl("nav.nations")}</a> -->
|
|
||||||
</div>
|
|
||||||
<div class="drawer md:hidden">
|
|
||||||
<input id="my-drawer-1" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content">
|
|
||||||
<label for="my-drawer-1" class="btn-ghost drawer-button">
|
|
||||||
<Icon
|
|
||||||
name="ph:list"
|
|
||||||
class="text-white text-4xl font-bold"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="drawer-side">
|
|
||||||
<label
|
|
||||||
for="my-drawer-1"
|
|
||||||
aria-label="close sidebar"
|
|
||||||
class="drawer-overlay"></label>
|
|
||||||
<ul
|
|
||||||
class="menu min-h-full w-80 p-4 bg-[url(/img/opacity-logo.png)] bg-no-repeat bg-contain bg-center bg-[#22523F] text-white"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="flex gap-2 justify-center items-center mb-8 mt-8"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="w-1/3 object-contain"
|
|
||||||
src="/img/logo-metalico.webp"
|
|
||||||
alt="Logo Centro del Reino de Paz y Justicia"
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
class="font-secondary text-colorPrimary font-bold leading-none py-2 text-lg"
|
|
||||||
>
|
|
||||||
<a href="/"
|
|
||||||
>{tl("nav.logo_line1")}<br />{
|
|
||||||
tl("nav.logo_line2")
|
|
||||||
}</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ul
|
|
||||||
class="font-primary font-bold flex flex-col gap-1 text-lg p-0"
|
|
||||||
>
|
|
||||||
{
|
|
||||||
sidebarNavItems.map((item) => (
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="hover:text-colorPrimary transition"
|
|
||||||
href={`/${currentLocale}${item.href}`}
|
|
||||||
>
|
|
||||||
{tl(item.key)}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
{isAdmin && (
|
|
||||||
<li>
|
|
||||||
<form method="POST" action="/api/admin/auth/logout">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="w-full text-left text-white hover:text-colorPrimary transition cursor-pointer"
|
|
||||||
>
|
|
||||||
Salir
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
<div class="w-50">
|
|
||||||
<Button
|
|
||||||
class="px-8 py-2 uppercase text-lg mt-8"
|
|
||||||
title={tl("nav.contact")}
|
|
||||||
url="#contact"
|
|
||||||
variant="primary"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown mt-10">
|
|
||||||
<div
|
|
||||||
tabindex="0"
|
|
||||||
role="button"
|
|
||||||
class="btn-ghost m-1 cursor-pointer"
|
|
||||||
>
|
|
||||||
<Icon name="ph:translate" class="text-2xl" />
|
|
||||||
</div>
|
|
||||||
<ul
|
|
||||||
tabindex="-1"
|
|
||||||
class="dropdown-content text-tertiary text-lg bg-colorPrimary menu z-1 w-52 p-2 shadow-sm"
|
|
||||||
>
|
|
||||||
{
|
|
||||||
languages.map((lang) => (
|
|
||||||
<li>
|
|
||||||
<a href={translatePath(lang.code)}>
|
|
||||||
{lang.icon && (
|
|
||||||
<Icon name={lang.icon} />
|
|
||||||
)}{" "}
|
|
||||||
{lang.label}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-50 hidden md:block">
|
|
||||||
<Button
|
|
||||||
class="px-4 py-2 uppercase"
|
|
||||||
title={tl("nav.contact")}
|
|
||||||
url="#contact"
|
|
||||||
variant="primary"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{isAdmin && (
|
|
||||||
<div class="hidden md:block">
|
|
||||||
<form method="POST" action="/api/admin/auth/logout">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="bg-[#22523F] text-[#EBE6D2] border-0 hover:bg-[#EBE6D2]/90 hover:text-tertiary uppercase rounded-none font-bold transition block text-center px-4 py-2 cursor-pointer"
|
|
||||||
>
|
|
||||||
Salir
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div class="dropdown dropdown-end md:block hidden">
|
|
||||||
<div
|
|
||||||
tabindex="0"
|
|
||||||
role="button"
|
|
||||||
class="btn-ghost m-1 cursor-pointer"
|
|
||||||
>
|
|
||||||
<Icon name="ph:translate" class="text-2xl" />
|
|
||||||
</div>
|
|
||||||
<ul
|
|
||||||
tabindex="-1"
|
|
||||||
class="dropdown-content text-tertiary text-lg bg-colorPrimary menu z-1 w-52 p-2 shadow-sm"
|
|
||||||
>
|
|
||||||
{
|
|
||||||
languages.map((lang) => (
|
|
||||||
<li>
|
|
||||||
<a href={translatePath(lang.code)}>
|
|
||||||
{lang.icon && <Icon name={lang.icon} />}{" "}
|
|
||||||
{lang.label}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
|
<nav
|
||||||
|
class="flex justify-evenly gap-10 items-center uppercase text-md text-white"
|
||||||
|
>
|
||||||
|
<div class="hidden md:flex gap-8 font-primary font-bold">
|
||||||
|
<a class="hover:text-colorPrimary transition" href=`/${locale}#somos`>{tl("nav.about")}</a>
|
||||||
|
<a class="hover:text-colorPrimary transition" href=`/${locale}#programs`>{tl("nav.programs")}</a>
|
||||||
|
<a class="hover:text-colorPrimary transition" href=`/${locale}#news`>{tl("nav.news")}</a>
|
||||||
|
</div>
|
||||||
|
<div class="drawer lg:hidden">
|
||||||
|
<input id="my-drawer-1" type="checkbox" class="drawer-toggle" />
|
||||||
|
<div class="drawer-content">
|
||||||
|
<!-- Page content here -->
|
||||||
|
<label for="my-drawer-1" class="btn-ghost drawer-button"><Icon name="ph:list" class="text-white text-4xl font-bold" /></label>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-side">
|
||||||
|
<label for="my-drawer-1" aria-label="close sidebar" class="drawer-overlay"></label>
|
||||||
|
<ul class="menu min-h-full w-80 p-4 bg-[url(/img/mid-logo-2.webp)] bg-no-repeat bg-contain bg-center bg-[#22523F] text-white">
|
||||||
|
<!-- Sidebar content here -->
|
||||||
|
<div class="flex gap-2 justify-center items-center mb-8 mt-8">
|
||||||
|
<img class="w-1/3 object-contain" src="/img/logo-metalico.webp" alt="Logo Centro del Reino de Paz y Justicia" />
|
||||||
|
<p class="font-secondary text-colorPrimary font-bold leading-none py-2 text-lg ">
|
||||||
|
<a href="/">{tl("nav.logo_line1")}<br/>{tl("nav.logo_line2")}</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="font-primary font-bold flex flex-col gap-1 text-lg p-0">
|
||||||
|
<li><a><a class="hover:text-colorPrimary transition" href="#somos">{tl("nav.about")}</a></a></li>
|
||||||
|
<li><a><a class="hover:text-colorPrimary transition" href="#programs">{tl("nav.programs")}</a></a></li>
|
||||||
|
<li><a><a class="hover:text-colorPrimary transition" href="#news">{tl("nav.news")}</a></a></li>
|
||||||
|
</div>
|
||||||
|
<div class="w-50">
|
||||||
|
<Button class="px-8 py-2 uppercase text-lg mt-8" title={tl("nav.contact")} url="#contact" variant="primary" />
|
||||||
|
</div>
|
||||||
|
<div class="dropdown mt-10">
|
||||||
|
<div tabindex="0" role="button" class="btn-ghost m-1 cursor-pointer"><Icon name="ph:translate" class="text-2xl" /></div>
|
||||||
|
<ul tabindex="-1" class="dropdown-content text-tertiary text-lg bg-colorPrimary menu z-1 w-52 p-2 shadow-sm">
|
||||||
|
<li><a href="/es">🇪🇸 Español</a></li>
|
||||||
|
<li><a href="/en">🇬🇧 English</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-50 hidden md:block">
|
||||||
|
<Button class="px-4 py-2 uppercase" title={tl("nav.contact")} url="#contact" variant="primary" />
|
||||||
|
</div>
|
||||||
|
<div class="dropdown dropdown-end lg:block hidden">
|
||||||
|
<div tabindex="0" role="button" class="btn-ghost m-1 cursor-pointer"><Icon name="ph:translate" class="text-2xl" /></div>
|
||||||
|
<ul tabindex="-1" class="dropdown-content text-tertiary text-lg bg-colorPrimary menu z-1 w-52 p-2 shadow-sm">
|
||||||
|
<li><a href="/es">🇪🇸 Español</a></li>
|
||||||
|
<li><a href="/en">🇬🇧 English</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<div class="font-secondary">
|
<div class="font-secondary">
|
||||||
<div class="top-16 relative mb container mx-auto">
|
<div class="top-16 relative mb container mx-auto">
|
||||||
<Header />
|
<Header />
|
||||||
</div>
|
</div>
|
||||||
<div class="h-screen pb-20 max-h-[700px] sm:max-h-[900px] md:max-h-[1080px] container bg-[url(/img/DRJBP-1.webp)] bg-no-repeat bg-contain bg-bottom mx-auto mt-16">
|
<div class="h-screen pb-20 max-h-[700px] sm:max-h-[900px] md:max-h-[1080px] container bg-[url(/img/DRJBP-1.webp)] bg-no-repeat bg-contain bg-bottom mx-auto mt-16">
|
||||||
|
|
||||||
<div class="grid md:grid-cols-2 h-full px-6">
|
<div class="grid md:grid-cols-2 h-full px-6">
|
||||||
<div class="gap-8 md:flex flex-col justify-end mt-14 md:mt-0">
|
<div class="gap-8 md:flex flex-col justify-end">
|
||||||
<img
|
<img
|
||||||
src="/img/logo-metalico.webp"
|
src="/img/logo-metalico.webp"
|
||||||
alt="Logo Metalico"
|
alt="Logo Metalico"
|
||||||
|
|
@ -37,7 +37,7 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<h2 class="text-[#EAE6D2] text-lg py-8">{tl("hero.body")}</h2>
|
<h2 class="text-[#EAE6D2] text-lg py-8">{tl("hero.body")}</h2>
|
||||||
<div class="w-16 self-end md:mt-64">
|
<div class="w-16 self-end md:mt-64">
|
||||||
<img
|
<img
|
||||||
src="/img/white-lion.png"
|
src="/img/white-dove.webp"
|
||||||
alt="White Dove"
|
alt="White Dove"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- DESKTOP -->
|
|
||||||
<div class="hidden md:block fixed left-0 top-1/2 -translate-y-1/2 z-[9999]">
|
|
||||||
<div
|
|
||||||
class="relative transition-all duration-300 ease-out"
|
|
||||||
:class="desktopOpen ? 'translate-x-0' : '-translate-x-[70%]'"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="absolute right-[-14px] top-1/2 -translate-y-1/2 bg-white shadow-md rounded-r-xl px-1 py-4 border border-gray-200 cursor-pointer"
|
|
||||||
@click="desktopOpen = !desktopOpen"
|
|
||||||
>
|
|
||||||
<div class="w-1 h-6 bg-gray-400 rounded-full"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="flex flex-col gap-4 bg-white/90 backdrop-blur-md py-4 px-4 rounded-r-2xl shadow-xl border border-gray-200">
|
|
||||||
<li class="border-b pb-3">
|
|
||||||
<a :href="twitterUrl" target="_blank">
|
|
||||||
<Icon icon="ph:x-logo-thin" class="text-2xl text-black" />
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="border-b pb-3">
|
|
||||||
<a :href="facebookUrl" target="_blank">
|
|
||||||
<Icon icon="ph:facebook-logo-thin" class="text-2xl text-black" />
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="border-b pb-3">
|
|
||||||
<a :href="whatsappUrl" target="_blank">
|
|
||||||
<Icon icon="ph:whatsapp-logo-thin" class="text-2xl text-black" />
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="border-b pb-3">
|
|
||||||
<a :href="linkedinUrl" target="_blank">
|
|
||||||
<Icon icon="ph:linkedin-logo-thin" class="text-2xl text-black" />
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button @click="copyLink" class="cursor-pointer">
|
|
||||||
<Icon :icon="copied ? 'ph:check-thin' : 'ph:link-thin'" class="text-2xl text-black" />
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md:hidden fixed bottom-6 right-6 z-[9999]">
|
|
||||||
<div class="flex flex-col items-end gap-2 mb-3">
|
|
||||||
<transition name="fade">
|
|
||||||
<div
|
|
||||||
v-if="open"
|
|
||||||
class="flex flex-col gap-3 bg-white/90 backdrop-blur-md p-3 rounded-2xl shadow-xl border border-gray-200"
|
|
||||||
>
|
|
||||||
<a :href="twitterUrl" target="_blank" class="text-gray-600 hover:text-black transition border-b pb-3">
|
|
||||||
<Icon icon="ph:x-logo-thin" class="text-2xl" />
|
|
||||||
</a>
|
|
||||||
<a :href="facebookUrl" target="_blank" class="text-gray-600 hover:text-blue-600 transition border-b pb-3">
|
|
||||||
<Icon icon="ph:facebook-logo-thin" class="text-2xl" />
|
|
||||||
</a>
|
|
||||||
<a :href="whatsappUrl" target="_blank" class="text-gray-600 hover:text-green-600 transition border-b pb-3">
|
|
||||||
<Icon icon="ph:whatsapp-logo-thin" class="text-2xl" />
|
|
||||||
</a>
|
|
||||||
<a :href="linkedinUrl" target="_blank" class="text-gray-600 hover:text-blue-700 transition border-b pb-3">
|
|
||||||
<Icon icon="ph:linkedin-logo-thin" class="text-2xl" />
|
|
||||||
</a>
|
|
||||||
<button @click="copyLink" class="text-gray-600 hover:text-emerald-600 transition">
|
|
||||||
<Icon :icon="copied ? 'ph:check-thin' : 'ph:link-thin'" class="text-2xl" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FAB PRINCIPAL -->
|
|
||||||
<button
|
|
||||||
@click="toggle"
|
|
||||||
class="bg-white/90 backdrop-blur-md border border-gray-200 shadow-xl rounded-full p-3 text-gray-700 hover:text-black transition"
|
|
||||||
>
|
|
||||||
<Icon :icon="open ? 'ph:x-thin' : 'ph:share-network-thin'" class="text-2xl" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed } from "vue"
|
|
||||||
import { Icon } from "@iconify/vue"
|
|
||||||
|
|
||||||
const props = defineProps({ url: { type: String, required: true } })
|
|
||||||
const open = ref(false)
|
|
||||||
const toggle = () => (open.value = !open.value)
|
|
||||||
|
|
||||||
const desktopOpen = ref(false) // controla el panel desktop
|
|
||||||
|
|
||||||
const copied = ref(false)
|
|
||||||
const copyLink = async () => {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(props.url)
|
|
||||||
copied.value = true
|
|
||||||
setTimeout(() => (copied.value = false), 1500)
|
|
||||||
} catch {
|
|
||||||
console.error("No se pudo copiar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const fullUrl = computed(() => window.location.href)
|
|
||||||
|
|
||||||
const encodedUrl = computed(() => encodeURIComponent(fullUrl.value))
|
|
||||||
const twitterUrl = computed(() => `https://twitter.com/intent/tweet?url=${encodedUrl.value}`)
|
|
||||||
const facebookUrl = computed(() => `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl.value}`)
|
|
||||||
const whatsappUrl = computed(() => `https://api.whatsapp.com/send?text=${encodedUrl.value}`)
|
|
||||||
const linkedinUrl = computed(() => `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl.value}`)
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="space-y-8">
|
|
||||||
<div v-if="loading" class="flex justify-center py-16">
|
|
||||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else-if="error" class="text-center py-10 text-error">{{ error }}</div>
|
|
||||||
|
|
||||||
<template v-else-if="stats">
|
|
||||||
<!-- Resumen -->
|
|
||||||
<section>
|
|
||||||
<h3 class="text-xs font-bold text-tertiary uppercase tracking-wide flex items-center gap-2 mb-3">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Resumen
|
|
||||||
</h3>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
|
|
||||||
<div class="stat bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box p-4">
|
|
||||||
<div class="stat-title text-tertiary/70 text-xs font-medium">Total voluntarios</div>
|
|
||||||
<div class="stat-value text-tertiary font-primary">{{ fmt(stats.total) }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box p-4">
|
|
||||||
<div class="stat-title text-tertiary/70 text-xs font-medium">Edad promedio</div>
|
|
||||||
<div class="stat-value text-tertiary font-primary">{{ stats.edad.promedio ?? "—" }} años</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box p-4">
|
|
||||||
<div class="stat-title text-tertiary/70 text-xs font-medium">Femenino</div>
|
|
||||||
<div class="stat-value text-tertiary font-primary">{{ fmt(sexo.f) }}</div>
|
|
||||||
<div class="stat-desc text-tertiary/60">{{ pct(sexo.f, sexo.total) }}% del total</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box p-4">
|
|
||||||
<div class="stat-title text-tertiary/70 text-xs font-medium">Masculino</div>
|
|
||||||
<div class="stat-value text-tertiary font-primary">{{ fmt(sexo.m) }}</div>
|
|
||||||
<div class="stat-desc text-tertiary/60">{{ pct(sexo.m, sexo.total) }}% del total</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Idiomas -->
|
|
||||||
<section>
|
|
||||||
<h3 class="text-xs font-bold text-tertiary uppercase tracking-wide flex items-center gap-2 mb-3">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Idiomas
|
|
||||||
</h3>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3">
|
|
||||||
<div
|
|
||||||
v-for="lang in stats.idiomas"
|
|
||||||
:key="lang.value"
|
|
||||||
class="stat bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box p-4"
|
|
||||||
>
|
|
||||||
<div class="stat-title text-tertiary/70 text-xs font-medium">{{ lang.label }}</div>
|
|
||||||
<div class="stat-value text-tertiary font-primary text-2xl">{{ fmt(lang.count) }}</div>
|
|
||||||
<div class="stat-desc text-tertiary/60">{{ pct(lang.count, stats.total) }}% del total</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Distribuciones -->
|
|
||||||
<section>
|
|
||||||
<h3 class="text-xs font-bold text-tertiary uppercase tracking-wide flex items-center gap-2 mb-3">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Distribuciones
|
|
||||||
</h3>
|
|
||||||
<div class="grid md:grid-cols-2 gap-4">
|
|
||||||
<div class="card bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box">
|
|
||||||
<div class="card-body p-4 sm:p-5">
|
|
||||||
<h4 class="card-title text-tertiary text-sm font-bold">Áreas de colaboración</h4>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<div v-for="item in topAreas" :key="item.value" class="flex items-center gap-3">
|
|
||||||
<span class="w-32 sm:w-44 shrink-0 text-sm text-tertiary truncate" :title="item.label">{{ item.label }}</span>
|
|
||||||
<progress class="progress progress-secondary flex-1" :value="item.count" :max="areasMax"></progress>
|
|
||||||
<span class="w-12 shrink-0 text-right text-sm font-semibold text-tertiary">{{ fmt(item.count) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box">
|
|
||||||
<div class="card-body p-4 sm:p-5">
|
|
||||||
<h4 class="card-title text-tertiary text-sm font-bold">Días disponibles</h4>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<div v-for="item in stats.dias" :key="item.value" class="flex items-center gap-3">
|
|
||||||
<span class="w-32 sm:w-44 shrink-0 text-sm text-tertiary truncate" :title="item.label">{{ item.label }}</span>
|
|
||||||
<progress class="progress progress-secondary flex-1" :value="item.count" :max="diasMax"></progress>
|
|
||||||
<span class="w-12 shrink-0 text-right text-sm font-semibold text-tertiary">{{ fmt(item.count) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box">
|
|
||||||
<div class="card-body p-4 sm:p-5">
|
|
||||||
<h4 class="card-title text-tertiary text-sm font-bold">Horario preferido</h4>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<div v-for="item in stats.horarios" :key="item.value" class="flex items-center gap-3">
|
|
||||||
<span class="w-32 sm:w-44 shrink-0 text-sm text-tertiary truncate" :title="item.label">{{ item.label }}</span>
|
|
||||||
<progress class="progress progress-secondary flex-1" :value="item.count" :max="horariosMax"></progress>
|
|
||||||
<span class="w-12 shrink-0 text-right text-sm font-semibold text-tertiary">{{ fmt(item.count) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box">
|
|
||||||
<div class="card-body p-4 sm:p-5">
|
|
||||||
<h4 class="card-title text-tertiary text-sm font-bold">Países</h4>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<div v-for="item in stats.paises" :key="item.value" class="flex items-center gap-3">
|
|
||||||
<span class="w-32 sm:w-44 shrink-0 text-sm text-tertiary truncate" :title="item.value">{{ item.value }}</span>
|
|
||||||
<progress class="progress progress-secondary flex-1" :value="item.count" :max="paisesMax"></progress>
|
|
||||||
<span class="w-12 shrink-0 text-right text-sm font-semibold text-tertiary">{{ fmt(item.count) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Disponibilidad y salud -->
|
|
||||||
<section>
|
|
||||||
<h3 class="text-xs font-bold text-tertiary uppercase tracking-wide flex items-center gap-2 mb-3">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Disponibilidad y salud
|
|
||||||
</h3>
|
|
||||||
<div class="card bg-colorPrimary ring-1 ring-colorSecondary/40 rounded-box">
|
|
||||||
<div class="card-body p-4 sm:p-6 grid md:grid-cols-2 gap-x-8 gap-y-5">
|
|
||||||
<div v-for="m in condMetrics" :key="m.title" class="space-y-1.5">
|
|
||||||
<div class="flex justify-between text-sm text-tertiary">
|
|
||||||
<span class="font-medium">{{ m.title }}</span>
|
|
||||||
<span>Sí {{ m.pct }}% · No {{ 100 - m.pct }}%</span>
|
|
||||||
</div>
|
|
||||||
<progress class="progress progress-secondary w-full" :value="m.si" :max="m.total"></progress>
|
|
||||||
<p class="text-xs text-tertiary/60">
|
|
||||||
Sí: {{ fmt(m.si) }} · No: {{ fmt(m.no) }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-1.5">
|
|
||||||
<div class="flex justify-between text-sm text-tertiary">
|
|
||||||
<span class="font-medium">Sexo</span>
|
|
||||||
<span>F {{ pct(sexo.f, sexo.total) }}% · M {{ pct(sexo.m, sexo.total) }}%</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex w-full h-3 rounded-none overflow-hidden bg-tertiary/15">
|
|
||||||
<div class="bg-tertiary h-full" :style="{ width: pct(sexo.f, sexo.total) + '%' }"></div>
|
|
||||||
<div class="bg-colorSecondary h-full" :style="{ width: pct(sexo.m, sexo.total) + '%' }"></div>
|
|
||||||
</div>
|
|
||||||
<p class="text-xs text-tertiary/60">
|
|
||||||
F: {{ fmt(sexo.f) }} · M: {{ fmt(sexo.m) }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed, onMounted } from "vue";
|
|
||||||
import { cachedFetch } from "../../lib/adminCache";
|
|
||||||
|
|
||||||
const loading = ref(false);
|
|
||||||
const error = ref("");
|
|
||||||
const stats = ref(null);
|
|
||||||
|
|
||||||
const fmt = (n) => Number(n || 0).toLocaleString("es");
|
|
||||||
const pct = (n, total) => (total ? Math.round(((n || 0) / total) * 100) : 0);
|
|
||||||
|
|
||||||
const sexo = computed(() => {
|
|
||||||
const s = stats.value?.sexo || [];
|
|
||||||
const f = s.find((x) => x.value === "F")?.count || 0;
|
|
||||||
const m = s.find((x) => x.value === "M")?.count || 0;
|
|
||||||
return { f, m, total: f + m };
|
|
||||||
});
|
|
||||||
|
|
||||||
const topAreas = computed(() => (stats.value?.areas || []).slice(0, 8));
|
|
||||||
const areasMax = computed(() => topAreas.value[0]?.count || 1);
|
|
||||||
const diasMax = computed(() => stats.value?.dias[0]?.count || 1);
|
|
||||||
const horariosMax = computed(() => stats.value?.horarios[0]?.count || 1);
|
|
||||||
const paisesMax = computed(() => stats.value?.paises[0]?.count || 1);
|
|
||||||
|
|
||||||
const condMetrics = computed(() => {
|
|
||||||
const c = stats.value?.condiciones;
|
|
||||||
if (!c) return [];
|
|
||||||
const mk = (title, key) => {
|
|
||||||
const si = c[key].si || 0;
|
|
||||||
const no = c[key].no || 0;
|
|
||||||
const total = si + no;
|
|
||||||
return { title, si, no, total, pct: total ? Math.round((si / total) * 100) : 0 };
|
|
||||||
};
|
|
||||||
return [
|
|
||||||
mk("Disponible fuera de ciudad", "fuera_ciudad"),
|
|
||||||
mk("Misiones internacionales", "misiones_internacionales"),
|
|
||||||
mk("Condición médica", "condicion_medica"),
|
|
||||||
mk("Voluntariado anterior", "voluntariado_anterior"),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetchStats() {
|
|
||||||
loading.value = true;
|
|
||||||
error.value = "";
|
|
||||||
try {
|
|
||||||
const res = await cachedFetch("/api/admin/voluntarios/stats", { ttl: 60 });
|
|
||||||
const json = await res.json();
|
|
||||||
if (!json.success) throw new Error(json.message || "Error al cargar estadísticas");
|
|
||||||
stats.value = json;
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(fetchStats);
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,179 +0,0 @@
|
||||||
<template>
|
|
||||||
<div ref="rootEl" class="relative">
|
|
||||||
<div
|
|
||||||
class="combobox-input input input-sm flex flex-wrap items-center gap-1 w-full cursor-text"
|
|
||||||
@click="focusInput"
|
|
||||||
>
|
|
||||||
<template v-if="multiple">
|
|
||||||
<span
|
|
||||||
v-for="item in currentValue"
|
|
||||||
:key="item"
|
|
||||||
class="badge badge-sm badge-neutral gap-1"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
<button type="button" class="btn btn-ghost btn-xs btn-circle" @click.stop="toggle(item)">✕</button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<input
|
|
||||||
ref="inputEl"
|
|
||||||
v-model="query"
|
|
||||||
type="text"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
class="flex-1 min-w-[4rem]"
|
|
||||||
@input="onInput"
|
|
||||||
@focus="open = true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul
|
|
||||||
v-if="open"
|
|
||||||
class="absolute z-30 mt-1 w-full max-h-64 overflow-y-auto bg-base-100 rounded-box shadow ring-1 ring-base-300"
|
|
||||||
@mousedown.prevent
|
|
||||||
>
|
|
||||||
<li v-if="loading" class="px-3 py-2 text-sm text-base-content/50 flex items-center gap-2">
|
|
||||||
<span class="loading loading-spinner loading-xs"></span> Cargando…
|
|
||||||
</li>
|
|
||||||
<li v-else-if="options.length === 0" class="px-3 py-2 text-sm text-base-content/50">
|
|
||||||
{{ multiple ? "Sin opciones" : "Sin sugerencias — sigue escribiendo" }}
|
|
||||||
</li>
|
|
||||||
<li v-for="opt in options" :key="opt.value">
|
|
||||||
<label
|
|
||||||
v-if="multiple"
|
|
||||||
class="flex items-center gap-2 px-3 py-1.5 hover:bg-base-200 cursor-pointer"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
class="checkbox checkbox-xs"
|
|
||||||
:checked="isSelected(opt.value)"
|
|
||||||
@change="toggle(opt.value)"
|
|
||||||
/>
|
|
||||||
<span class="flex-1 text-sm">
|
|
||||||
{{ opt.value }}
|
|
||||||
<span class="text-xs text-base-content/50">({{ opt.count }})</span>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<button
|
|
||||||
v-else
|
|
||||||
type="button"
|
|
||||||
class="flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm hover:bg-base-200"
|
|
||||||
@click="pick(opt.value)"
|
|
||||||
>
|
|
||||||
<span class="truncate">{{ opt.value }}</span>
|
|
||||||
<span class="text-xs text-base-content/50 shrink-0">({{ opt.count }})</span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
|
||||||
import { cachedFetch } from "../../lib/adminCache";
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
field: { type: String, required: true },
|
|
||||||
placeholder: { type: String, default: "Escribir…" },
|
|
||||||
multiple: { type: Boolean, default: false },
|
|
||||||
limit: { type: Number, default: 25 },
|
|
||||||
});
|
|
||||||
|
|
||||||
const modelValue = defineModel({ type: [String, Array], default: "" });
|
|
||||||
|
|
||||||
const rootEl = ref(null);
|
|
||||||
const inputEl = ref(null);
|
|
||||||
const query = ref("");
|
|
||||||
const open = ref(false);
|
|
||||||
const loading = ref(false);
|
|
||||||
const options = ref([]);
|
|
||||||
|
|
||||||
let fetchTimer = null;
|
|
||||||
let fetchVersion = 0;
|
|
||||||
|
|
||||||
const currentValue = () => {
|
|
||||||
const v = modelValue.value;
|
|
||||||
return Array.isArray(v) ? v : typeof v === "string" ? v : "";
|
|
||||||
};
|
|
||||||
|
|
||||||
function focusInput() {
|
|
||||||
inputEl.value?.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSelected(v) {
|
|
||||||
return currentValue().includes(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(v) {
|
|
||||||
const arr = [...currentValue()];
|
|
||||||
const i = arr.indexOf(v);
|
|
||||||
if (i >= 0) arr.splice(i, 1);
|
|
||||||
else arr.push(v);
|
|
||||||
modelValue.value = arr;
|
|
||||||
query.value = "";
|
|
||||||
scheduleFetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
function pick(v) {
|
|
||||||
modelValue.value = v;
|
|
||||||
query.value = v;
|
|
||||||
open.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInput() {
|
|
||||||
if (!props.multiple) modelValue.value = query.value;
|
|
||||||
scheduleFetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchOptions() {
|
|
||||||
loading.value = true;
|
|
||||||
const version = ++fetchVersion;
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set("field", props.field);
|
|
||||||
params.set("limit", String(props.limit));
|
|
||||||
if (query.value.trim().length >= 2) params.set("q", query.value.trim());
|
|
||||||
try {
|
|
||||||
const res = await cachedFetch(`/api/admin/voluntarios/distinct?${params.toString()}`, { ttl: 300 });
|
|
||||||
const json = await res.json();
|
|
||||||
if (version !== fetchVersion) return;
|
|
||||||
options.value = json.success ? json.data : [];
|
|
||||||
} catch {
|
|
||||||
if (version === fetchVersion) options.value = [];
|
|
||||||
} finally {
|
|
||||||
if (version === fetchVersion) loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scheduleFetch() {
|
|
||||||
clearTimeout(fetchTimer);
|
|
||||||
fetchTimer = setTimeout(fetchOptions, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => modelValue.value,
|
|
||||||
(val) => {
|
|
||||||
if (!props.multiple && query.value !== val) query.value = typeof val === "string" ? val : "";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function onDocClick(e) {
|
|
||||||
if (rootEl.value && !rootEl.value.contains(e.target)) open.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
document.addEventListener("mousedown", onDocClick);
|
|
||||||
scheduleFetch();
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
document.removeEventListener("mousedown", onDocClick);
|
|
||||||
clearTimeout(fetchTimer);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.combobox-input {
|
|
||||||
height: auto;
|
|
||||||
min-height: 2rem;
|
|
||||||
padding-top: 0.125rem;
|
|
||||||
padding-bottom: 0.125rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,285 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="space-y-4">
|
|
||||||
<div v-if="loading" class="flex justify-center py-16">
|
|
||||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else-if="error" class="text-center py-10 text-error">{{ error }}</div>
|
|
||||||
|
|
||||||
<div v-else-if="data" class="space-y-6">
|
|
||||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2">
|
|
||||||
<h3 class="text-lg sm:text-xl font-bold">
|
|
||||||
{{ data.nombre }} {{ data.segundo_nombre }} {{ data.apellido }}
|
|
||||||
</h3>
|
|
||||||
<span class="font-mono text-sm opacity-70">#{{ data.numero_voluntario }}</span>
|
|
||||||
<span class="badge badge-sm" :class="badgeClass(data.status)">{{ data.status }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section
|
|
||||||
v-for="sec in sectionsWithData"
|
|
||||||
:key="sec.key"
|
|
||||||
class="rounded-box ring-1 ring-base-300 bg-base-100/60 overflow-hidden"
|
|
||||||
>
|
|
||||||
<h4 class="font-medium text-sm uppercase tracking-wide px-4 py-3 border-b border-base-200">
|
|
||||||
{{ sec.title }}
|
|
||||||
</h4>
|
|
||||||
<dl class="divide-y divide-base-200/70 text-sm">
|
|
||||||
<div
|
|
||||||
v-for="f in sec.fields"
|
|
||||||
:key="f.key"
|
|
||||||
class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1"
|
|
||||||
>
|
|
||||||
<dt class="text-base-content/60">{{ f.label }}</dt>
|
|
||||||
<dd class="min-w-0 break-words">
|
|
||||||
<div v-if="f.isList" :class="f.isLongList ? 'space-y-1.5' : 'flex flex-wrap gap-1.5'">
|
|
||||||
<div
|
|
||||||
v-if="f.isLongList"
|
|
||||||
v-for="(item, i) in f.displayValues"
|
|
||||||
:key="'list-' + i"
|
|
||||||
class="text-sm border-l-2 border-base-300 pl-2"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
v-else
|
|
||||||
v-for="(item, i) in f.displayValues"
|
|
||||||
:key="'chip-' + i"
|
|
||||||
class="badge badge-sm badge-ghost border border-base-300 whitespace-normal text-left"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span v-else>{{ f.displayText }}</span>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section
|
|
||||||
v-if="extraRows.length"
|
|
||||||
class="rounded-box ring-1 ring-base-300 bg-base-100/60 overflow-hidden"
|
|
||||||
>
|
|
||||||
<h4 class="font-medium text-sm uppercase tracking-wide px-4 py-3 border-b border-base-200">
|
|
||||||
Otros datos
|
|
||||||
</h4>
|
|
||||||
<dl class="divide-y divide-base-200/70 text-sm">
|
|
||||||
<div
|
|
||||||
v-for="r in extraRows"
|
|
||||||
:key="r.rawKey"
|
|
||||||
class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1"
|
|
||||||
>
|
|
||||||
<dt class="text-base-content/60">{{ r.key }}</dt>
|
|
||||||
<dd class="min-w-0 break-words">{{ r.value }}</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="rounded-box ring-1 ring-base-300 bg-base-100/60 overflow-hidden">
|
|
||||||
<h4 class="font-medium text-sm uppercase tracking-wide px-4 py-3 border-b border-base-200">
|
|
||||||
Sistema
|
|
||||||
</h4>
|
|
||||||
<dl class="divide-y divide-base-200/70 text-sm">
|
|
||||||
<div class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1">
|
|
||||||
<dt class="text-base-content/60">ID</dt>
|
|
||||||
<dd class="font-mono break-all">{{ data.id }}</dd>
|
|
||||||
</div>
|
|
||||||
<div class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1">
|
|
||||||
<dt class="text-base-content/60">Versión de formulario</dt>
|
|
||||||
<dd>{{ data.form_version || "—" }}</dd>
|
|
||||||
</div>
|
|
||||||
<div class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1">
|
|
||||||
<dt class="text-base-content/60">Correo enviado</dt>
|
|
||||||
<dd>{{ formatDateTime(data.email_sent_at) }}</dd>
|
|
||||||
</div>
|
|
||||||
<div class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1">
|
|
||||||
<dt class="text-base-content/60">Registrado</dt>
|
|
||||||
<dd>{{ formatDateTime(data.submitted_at) }}</dd>
|
|
||||||
</div>
|
|
||||||
<div class="px-4 py-2.5 grid sm:grid-cols-[220px_1fr] gap-x-4 gap-y-1">
|
|
||||||
<dt class="text-base-content/60">Actualizado</dt>
|
|
||||||
<dd>{{ formatDateTime(data.updated_at) }}</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed, watch, onMounted } from "vue";
|
|
||||||
import { cachedFetch } from "../../lib/adminCache";
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
numero: { type: [Number, String], required: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
const CORE_COLUMN_MAP = {
|
|
||||||
nombre: "nombre",
|
|
||||||
segundo_nombre: "segundo_nombre",
|
|
||||||
apellido: "apellido",
|
|
||||||
correo: "correo",
|
|
||||||
fecha_nacimiento: "fecha_nacimiento",
|
|
||||||
nacionalidad: "nacionalidad",
|
|
||||||
sexo: "sexo",
|
|
||||||
direccion_completa: "direccion",
|
|
||||||
ciudad: "ciudad",
|
|
||||||
estado: "estado",
|
|
||||||
pais: "pais",
|
|
||||||
postal: "codigo_postal",
|
|
||||||
telefono: "telefono",
|
|
||||||
whatsapp: "whatsapp",
|
|
||||||
profesion: "profesion",
|
|
||||||
lugar_trabajo_actual: "lugar_trabajo",
|
|
||||||
nivel_academico: "nivel_academico",
|
|
||||||
};
|
|
||||||
|
|
||||||
const loading = ref(false);
|
|
||||||
const error = ref("");
|
|
||||||
const data = ref(null);
|
|
||||||
const sections = ref([]);
|
|
||||||
|
|
||||||
function pretty(v) {
|
|
||||||
if (v === "si") return "Sí";
|
|
||||||
if (v === "no") return "No";
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fallbackLabel(key) {
|
|
||||||
if (key.startsWith("idioma_nivel_")) return `Nivel de ${key.slice("idioma_nivel_".length)}`;
|
|
||||||
if (key === "locale") return "Idioma de la solicitud";
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
const respuestasByKey = computed(() => {
|
|
||||||
const map = {};
|
|
||||||
for (const r of data.value?.respuestas || []) {
|
|
||||||
(map[r.key] ||= []).push(r.value);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
});
|
|
||||||
|
|
||||||
function fieldTokens(field) {
|
|
||||||
let values;
|
|
||||||
if (field.key === "documentos") {
|
|
||||||
const s = [data.value.documento_tipo, data.value.documento_nro].filter(Boolean).join(" ");
|
|
||||||
values = s ? [s] : [];
|
|
||||||
} else if (CORE_COLUMN_MAP[field.key]) {
|
|
||||||
const v = data.value[CORE_COLUMN_MAP[field.key]];
|
|
||||||
values = v === null || v === undefined || v === "" ? [] : [String(v)];
|
|
||||||
} else {
|
|
||||||
values = respuestasByKey.value[field.key] || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const tokens = [];
|
|
||||||
for (const raw of values) {
|
|
||||||
for (const part of String(raw).split(",")) {
|
|
||||||
const tok = part.trim();
|
|
||||||
if (!tok) continue;
|
|
||||||
const opt = (field.options || []).find((o) => o.value === tok);
|
|
||||||
let display = (opt ? opt.label : pretty(tok)).replace(/<[^>]*>/g, "");
|
|
||||||
if (field.tipo === "date" || field.key === "fecha_nacimiento") {
|
|
||||||
const d = new Date(display);
|
|
||||||
if (!isNaN(d)) {
|
|
||||||
display = d.toLocaleDateString("es", { year: "numeric", month: "2-digit", day: "2-digit" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens.push(display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sectionsWithData = computed(() => {
|
|
||||||
if (!data.value) return [];
|
|
||||||
return sections.value
|
|
||||||
.map((sec) => ({
|
|
||||||
...sec,
|
|
||||||
fields: sec.fields
|
|
||||||
.map((f) => {
|
|
||||||
const tokens = fieldTokens(f);
|
|
||||||
if (!tokens.length) return null;
|
|
||||||
return {
|
|
||||||
...f,
|
|
||||||
isList: f.tipo === "checkbox" && tokens.length > 1,
|
|
||||||
isLongList: f.tipo === "checkbox" && tokens.length > 1 && tokens.some((t) => t.length > 40),
|
|
||||||
displayValues: tokens,
|
|
||||||
displayText: tokens.join(", "),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter(Boolean),
|
|
||||||
}))
|
|
||||||
.filter((sec) => sec.fields.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
const extraRows = computed(() => {
|
|
||||||
if (!data.value) return [];
|
|
||||||
const known = new Set();
|
|
||||||
for (const sec of sections.value) for (const f of sec.fields) known.add(f.key);
|
|
||||||
const rows = [];
|
|
||||||
for (const [key, vals] of Object.entries(respuestasByKey.value)) {
|
|
||||||
if (known.has(key)) continue;
|
|
||||||
const tokens = [];
|
|
||||||
for (const raw of vals) {
|
|
||||||
for (const part of String(raw).split(",")) {
|
|
||||||
const t = part.trim();
|
|
||||||
if (t) tokens.push(pretty(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!tokens.length) continue;
|
|
||||||
rows.push({ key: fallbackLabel(key), rawKey: key, value: tokens.join(", ") });
|
|
||||||
}
|
|
||||||
return rows;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetchData() {
|
|
||||||
loading.value = true;
|
|
||||||
error.value = "";
|
|
||||||
try {
|
|
||||||
const res = await cachedFetch(`/api/admin/voluntarios/${props.numero}`, { ttl: 60 });
|
|
||||||
const json = await res.json();
|
|
||||||
if (!json.success) throw new Error(json.message || "Voluntario no encontrado");
|
|
||||||
data.value = json.data;
|
|
||||||
sections.value = json.form.sections;
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.numero,
|
|
||||||
() => {
|
|
||||||
data.value = null;
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function formatDateTime(iso) {
|
|
||||||
if (!iso) return "—";
|
|
||||||
const d = new Date(iso);
|
|
||||||
if (isNaN(d)) return "—";
|
|
||||||
return d.toLocaleString("es", {
|
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function badgeClass(s) {
|
|
||||||
switch (s) {
|
|
||||||
case "aprobado":
|
|
||||||
return "badge-success";
|
|
||||||
case "rechazado":
|
|
||||||
return "badge-error";
|
|
||||||
case "legacy":
|
|
||||||
return "badge-warning";
|
|
||||||
default:
|
|
||||||
return "badge-neutral";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(fetchData);
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,605 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="space-y-4">
|
|
||||||
<!-- Filtros -->
|
|
||||||
<div class="bg-colorPrimary border-l-4 border-colorSecondary p-4 rounded-box space-y-3 shadow-lg shadow-tertiary/20">
|
|
||||||
<div class="flex flex-col md:flex-row gap-3 items-end">
|
|
||||||
<div class="flex-1 w-full">
|
|
||||||
<label class="label py-0 text-xs font-medium">Buscar</label>
|
|
||||||
<input
|
|
||||||
v-model="search"
|
|
||||||
type="text"
|
|
||||||
placeholder="Nombre, correo, teléfono, documento…"
|
|
||||||
class="input input-bordered input-sm w-full"
|
|
||||||
@input="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="w-full md:w-52">
|
|
||||||
<label class="label py-0 text-xs font-medium">Status</label>
|
|
||||||
<details class="dropdown w-full">
|
|
||||||
<summary class="btn btn-sm btn-outline w-full justify-between">
|
|
||||||
<span class="truncate">{{ statusLabel }}</span>
|
|
||||||
<span class="opacity-60">▾</span>
|
|
||||||
</summary>
|
|
||||||
<ul class="menu dropdown-content bg-base-100 rounded-box shadow ring-1 ring-base-300 z-20 w-56 max-h-64 overflow-y-auto">
|
|
||||||
<li v-for="s in statuses" :key="s">
|
|
||||||
<label class="flex items-center gap-2 py-1.5">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
:value="s"
|
|
||||||
v-model="selectedStatuses"
|
|
||||||
class="checkbox checkbox-xs"
|
|
||||||
@change="applyFilters"
|
|
||||||
/>
|
|
||||||
<span>{{ s }}</span>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button class="btn btn-ghost btn-sm text-tertiary" @click="clearFilters">Limpiar</button>
|
|
||||||
<button class="btn btn-primary btn-sm" @click="showFilters = !showFilters">
|
|
||||||
{{ showFilters ? "Ocultar filtros" : "Filtros" }}
|
|
||||||
<span v-if="activeFilterCount" class="badge badge-sm bg-tertiary text-colorPrimary border-0">{{ activeFilterCount }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Chips de filtros activos -->
|
|
||||||
<div v-if="activeChips.length" class="flex flex-wrap gap-1.5">
|
|
||||||
<span
|
|
||||||
v-for="chip in activeChips"
|
|
||||||
:key="chip.key"
|
|
||||||
class="badge badge-sm bg-white gap-1 border border-colorSecondary/60 text-tertiary"
|
|
||||||
>
|
|
||||||
{{ chip.label }}
|
|
||||||
<button type="button" class="opacity-60 hover:opacity-100" @click="chip.remove()">✕</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Panel de filtros -->
|
|
||||||
<div v-if="showFilters" class="border-t border-colorSecondary/40 pt-3 space-y-4">
|
|
||||||
<div>
|
|
||||||
<p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Fecha y edad
|
|
||||||
</p>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Desde</label>
|
|
||||||
<input v-model="desde" type="date" class="input input-bordered input-sm w-full" @change="applyFilters" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Hasta</label>
|
|
||||||
<input v-model="hasta" type="date" class="input input-bordered input-sm w-full" @change="applyFilters" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Edad mín</label>
|
|
||||||
<input v-model="edadMin" type="number" min="0" max="120" class="input input-bordered input-sm w-full" @change="applyFilters" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Edad máx</label>
|
|
||||||
<input v-model="edadMax" type="number" min="0" max="120" class="input input-bordered input-sm w-full" @change="applyFilters" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Ubicación
|
|
||||||
</p>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">País</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="selectedPaises"
|
|
||||||
field="pais"
|
|
||||||
multiple
|
|
||||||
placeholder="Buscar país…"
|
|
||||||
@update:modelValue="applyFilters"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Nacionalidad</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="nacionalidad"
|
|
||||||
field="nacionalidad"
|
|
||||||
placeholder="Buscar…"
|
|
||||||
@update:modelValue="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Sexo</label>
|
|
||||||
<select v-model="sexo" class="select select-bordered select-sm w-full" @change="applyFilters">
|
|
||||||
<option value="">Todos</option>
|
|
||||||
<option value="M">M</option>
|
|
||||||
<option value="F">F</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Ciudad</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="coreText.ciudad"
|
|
||||||
field="ciudad"
|
|
||||||
placeholder="Buscar…"
|
|
||||||
@update:modelValue="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Estado</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="coreText.estado"
|
|
||||||
field="estado"
|
|
||||||
placeholder="Buscar…"
|
|
||||||
@update:modelValue="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Perfil
|
|
||||||
</p>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Profesión</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="coreText.profesion"
|
|
||||||
field="profesion"
|
|
||||||
placeholder="Buscar…"
|
|
||||||
@update:modelValue="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Nivel académico</label>
|
|
||||||
<SearchableCombobox
|
|
||||||
v-model="coreText.nivel_academico"
|
|
||||||
field="nivel_academico"
|
|
||||||
placeholder="Buscar…"
|
|
||||||
@update:modelValue="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Documento</label>
|
|
||||||
<input v-model="coreText.documento_nro" type="text" class="input input-bordered input-sm w-full" @input="onSearch" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="label py-0 text-xs font-medium">Versión de formulario</label>
|
|
||||||
<select v-model="formVersion" class="select select-bordered select-sm w-full" @change="applyFilters">
|
|
||||||
<option value="">Todas</option>
|
|
||||||
<option v-for="f in formVersions" :key="f" :value="f">{{ f }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
|
|
||||||
<span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Preferencias y condiciones
|
|
||||||
</p>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
|
|
||||||
<div v-for="f in responseFields" :key="f">
|
|
||||||
<label class="label py-0 text-xs font-medium">{{ respLabels[f] }}</label>
|
|
||||||
<select v-model="respFilters[f]" class="select select-bordered select-sm w-full" @change="applyFilters">
|
|
||||||
<option value="">Todos</option>
|
|
||||||
<option v-for="o in respFilterOptions[f]" :key="o" :value="o">{{ o }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Tabla -->
|
|
||||||
<div class="overflow-x-auto bg-base-100 rounded-box shadow ring-1 ring-base-300">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<thead>
|
|
||||||
<tr class="text-xs uppercase">
|
|
||||||
<th class="cursor-pointer select-none" @click="toggleSort('numero_voluntario')">#</th>
|
|
||||||
<th class="cursor-pointer select-none" @click="toggleSort('nombre')">Nombre completo</th>
|
|
||||||
<th>Correo</th>
|
|
||||||
<th>Teléfono</th>
|
|
||||||
<th class="cursor-pointer select-none" @click="toggleSort('pais')">País</th>
|
|
||||||
<th>Ciudad</th>
|
|
||||||
<th>Idiomas</th>
|
|
||||||
<th>Áreas</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th class="cursor-pointer select-none" @click="toggleSort('submitted_at')">Fecha</th>
|
|
||||||
<th class="w-20 text-right">Acción</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-if="loading">
|
|
||||||
<td colspan="11" class="text-center py-10">
|
|
||||||
<span class="loading loading-spinner loading-md text-primary"></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-else-if="error">
|
|
||||||
<td colspan="11" class="text-center py-10 text-error">{{ error }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-else-if="rows.length === 0">
|
|
||||||
<td colspan="11" class="text-center py-10 text-base-content/40">Sin resultados</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-for="row in rows" :key="row.id" class="hover:bg-base-200/50 cursor-pointer" @click="openDetail(row)">
|
|
||||||
<td class="font-mono">{{ row.numero_voluntario }}</td>
|
|
||||||
<td class="font-medium whitespace-nowrap">{{ row.nombre_completo }}</td>
|
|
||||||
<td class="max-w-[220px] truncate">{{ row.correo }}</td>
|
|
||||||
<td class="whitespace-nowrap">{{ row.telefono || "—" }}</td>
|
|
||||||
<td class="whitespace-nowrap">{{ row.pais || "—" }}</td>
|
|
||||||
<td class="whitespace-nowrap">{{ row.ciudad || "—" }}</td>
|
|
||||||
<td class="max-w-[200px] truncate" :title="row.idioma">{{ row.idioma || "—" }}</td>
|
|
||||||
<td class="max-w-[200px] truncate" :title="row.areas_colaborar">{{ row.areas_colaborar || "—" }}</td>
|
|
||||||
<td>
|
|
||||||
<span class="badge badge-sm" :class="badgeClass(row.status)">{{ row.status || "pendiente" }}</span>
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap">{{ formatDate(row.submitted_at) }}</td>
|
|
||||||
<td class="text-right">
|
|
||||||
<button class="btn btn-ghost btn-xs" title="Ver detalle" @click.stop="openDetail(row)">Ver</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Paginación -->
|
|
||||||
<div class="flex items-center justify-between flex-wrap gap-3">
|
|
||||||
<p class="text-sm text-amber-200">
|
|
||||||
{{ total }} registros · página {{ page }} de {{ totalPages || 1 }}
|
|
||||||
</p>
|
|
||||||
<div class="join">
|
|
||||||
<button class="join-item btn btn-sm" :disabled="page <= 1" @click="goPage(page - 1)">«</button>
|
|
||||||
<button
|
|
||||||
v-for="p in pageNumbers"
|
|
||||||
:key="p"
|
|
||||||
class="join-item btn btn-sm"
|
|
||||||
:class="p === page ? 'btn-primary' : ''"
|
|
||||||
@click="goPage(p)"
|
|
||||||
>
|
|
||||||
{{ p }}
|
|
||||||
</button>
|
|
||||||
<button class="join-item btn btn-sm" :disabled="page >= totalPages" @click="goPage(page + 1)">»</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Modal de detalle -->
|
|
||||||
<Teleport v-if="detailNumero !== null" to="body">
|
|
||||||
<div class="fixed inset-0 z-[60] overflow-y-auto">
|
|
||||||
<div class="fixed inset-0 bg-black/60" @click="closeDetail"></div>
|
|
||||||
<div class="relative min-h-full flex items-center justify-center p-4 sm:p-6">
|
|
||||||
<div class="w-full max-w-3xl max-h-[85vh] overflow-y-auto rounded-box bg-base-100 shadow-2xl ring-1 ring-base-300">
|
|
||||||
<div class="sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-base-100 border-b border-base-200">
|
|
||||||
<span class="text-sm font-semibold">Detalle del voluntario</span>
|
|
||||||
<button class="btn btn-ghost btn-sm" @click="closeDetail">✕</button>
|
|
||||||
</div>
|
|
||||||
<div class="p-4">
|
|
||||||
<VoluntarioDetail :numero="detailNumero" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Teleport>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, computed, watch, onMounted, onUnmounted } from "vue";
|
|
||||||
import SearchableCombobox from "./SearchableCombobox.vue";
|
|
||||||
import VoluntarioDetail from "./VoluntarioDetail.vue";
|
|
||||||
import { cachedFetch } from "../../lib/adminCache";
|
|
||||||
|
|
||||||
const rows = ref([]);
|
|
||||||
const total = ref(0);
|
|
||||||
const page = ref(1);
|
|
||||||
const totalPages = ref(1);
|
|
||||||
const limit = 25;
|
|
||||||
const loading = ref(false);
|
|
||||||
const error = ref("");
|
|
||||||
|
|
||||||
const detailNumero = ref(null);
|
|
||||||
let returnPath = "";
|
|
||||||
|
|
||||||
function slugUrl(numero) {
|
|
||||||
const m = window.location.pathname.match(/^\/([a-z]{2})\/admin/);
|
|
||||||
const locale = m ? m[1] : "es";
|
|
||||||
return `/${locale}/admin/voluntario/${numero}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openDetail(row) {
|
|
||||||
returnPath = window.location.pathname;
|
|
||||||
detailNumero.value = row.numero_voluntario;
|
|
||||||
history.pushState({ voluntario: true }, "", slugUrl(row.numero_voluntario));
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeDetail() {
|
|
||||||
detailNumero.value = null;
|
|
||||||
history.replaceState(null, "", returnPath || window.location.pathname);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopstate() {
|
|
||||||
if (detailNumero.value !== null) detailNumero.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onKeydown(e) {
|
|
||||||
if (e.key === "Escape" && detailNumero.value !== null) closeDetail();
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(detailNumero, (v) => {
|
|
||||||
document.body.style.overflow = v === null ? "" : "hidden";
|
|
||||||
});
|
|
||||||
|
|
||||||
const search = ref("");
|
|
||||||
const selectedStatuses = ref([]);
|
|
||||||
const selectedPaises = ref([]);
|
|
||||||
const sort = ref("submitted_at");
|
|
||||||
const order = ref("desc");
|
|
||||||
const showFilters = ref(false);
|
|
||||||
|
|
||||||
const desde = ref("");
|
|
||||||
const hasta = ref("");
|
|
||||||
const edadMin = ref("");
|
|
||||||
const edadMax = ref("");
|
|
||||||
|
|
||||||
const coreText = reactive({
|
|
||||||
ciudad: "",
|
|
||||||
estado: "",
|
|
||||||
profesion: "",
|
|
||||||
nivel_academico: "",
|
|
||||||
documento_nro: "",
|
|
||||||
});
|
|
||||||
const sexo = ref("");
|
|
||||||
const nacionalidad = ref("");
|
|
||||||
const formVersion = ref("");
|
|
||||||
|
|
||||||
const responseFields = [
|
|
||||||
"idioma",
|
|
||||||
"areas_colaborar",
|
|
||||||
"dias_disponibles",
|
|
||||||
"horario_preferido",
|
|
||||||
"fuera_ciudad",
|
|
||||||
"misiones_internacionales",
|
|
||||||
"condicion_medica",
|
|
||||||
"voluntariado_anterior",
|
|
||||||
];
|
|
||||||
const respFilters = reactive(Object.fromEntries(responseFields.map((f) => [f, ""])));
|
|
||||||
|
|
||||||
const respLabels = {
|
|
||||||
idioma: "Idioma",
|
|
||||||
areas_colaborar: "Áreas de colaboración",
|
|
||||||
dias_disponibles: "Días disponibles",
|
|
||||||
horario_preferido: "Horario preferido",
|
|
||||||
fuera_ciudad: "Disponible fuera de ciudad",
|
|
||||||
misiones_internacionales: "Misiones internacionales",
|
|
||||||
condicion_medica: "Condición médica",
|
|
||||||
voluntariado_anterior: "Voluntariado anterior",
|
|
||||||
};
|
|
||||||
|
|
||||||
const respFilterOptions = {
|
|
||||||
idioma: ["Espanol", "Ingles", "Hebreo", "Portugues", "Frances", "Otro"],
|
|
||||||
areas_colaborar: [
|
|
||||||
"Ayuda Humanitaria", "Educacion", "Desarrollo Comunitario", "Liderazgo",
|
|
||||||
"Logistica", "Organizacion de Eventos", "Comunicacion Institucional",
|
|
||||||
"Fotografia y Medios", "Recaudacion de Fondos", "Gestion de Proyectos",
|
|
||||||
"Traduccion e Interpretacion", "Asesoria Juridica", "Servicios Medicos",
|
|
||||||
"Diplomacia Publica", "Administracion", "Tecnologia e Innovacion", "Otra",
|
|
||||||
],
|
|
||||||
dias_disponibles: ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"],
|
|
||||||
horario_preferido: ["Manana", "Tarde", "Noche", "Segun necesidades"],
|
|
||||||
fuera_ciudad: ["si", "no"],
|
|
||||||
misiones_internacionales: ["si", "no"],
|
|
||||||
condicion_medica: ["si", "no"],
|
|
||||||
voluntariado_anterior: ["si", "no"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const statuses = ref([]);
|
|
||||||
const formVersions = ref([]);
|
|
||||||
|
|
||||||
let searchTimer = null;
|
|
||||||
|
|
||||||
const statusLabel = computed(() =>
|
|
||||||
selectedStatuses.value.length ? selectedStatuses.value.join(", ") : "Todos"
|
|
||||||
);
|
|
||||||
|
|
||||||
const activeFilterCount = computed(() => activeChips.value.length);
|
|
||||||
|
|
||||||
const activeChips = computed(() => {
|
|
||||||
const chips = [];
|
|
||||||
const add = (key, label, remove) => chips.push({ key, label, remove });
|
|
||||||
|
|
||||||
if (search.value.trim()) add("q", `Búsqueda: ${search.value.trim()}`, () => {
|
|
||||||
search.value = "";
|
|
||||||
onSearch();
|
|
||||||
});
|
|
||||||
for (const s of selectedStatuses.value) add(`status-${s}`, `Status: ${s}`, () => {
|
|
||||||
selectedStatuses.value = selectedStatuses.value.filter((x) => x !== s);
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
for (const p of selectedPaises.value) add(`pais-${p}`, `País: ${p}`, () => {
|
|
||||||
selectedPaises.value = selectedPaises.value.filter((x) => x !== p);
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (desde.value) add("desde", `Desde: ${desde.value}`, () => {
|
|
||||||
desde.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (hasta.value) add("hasta", `Hasta: ${hasta.value}`, () => {
|
|
||||||
hasta.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (edadMin.value) add("edad_min", `Edad mín: ${edadMin.value}`, () => {
|
|
||||||
edadMin.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (edadMax.value) add("edad_max", `Edad máx: ${edadMax.value}`, () => {
|
|
||||||
edadMax.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
for (const [k, v] of Object.entries(coreText)) {
|
|
||||||
if (v) {
|
|
||||||
const label = { ciudad: "Ciudad", estado: "Estado", profesion: "Profesión", nivel_academico: "Nivel académico", documento_nro: "Documento" }[k];
|
|
||||||
add(`core-${k}`, `${label}: ${v}`, () => {
|
|
||||||
coreText[k] = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sexo.value) add("sexo", `Sexo: ${sexo.value}`, () => {
|
|
||||||
sexo.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (nacionalidad.value) add("nacionalidad", `Nacionalidad: ${nacionalidad.value}`, () => {
|
|
||||||
nacionalidad.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
if (formVersion.value) add("form_version", `Versión: ${formVersion.value}`, () => {
|
|
||||||
formVersion.value = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
for (const f of responseFields) {
|
|
||||||
if (respFilters[f]) add(`resp-${f}`, `${respLabels[f]}: ${respFilters[f]}`, () => {
|
|
||||||
respFilters[f] = "";
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return chips;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetchData() {
|
|
||||||
loading.value = true;
|
|
||||||
error.value = "";
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set("page", String(page.value));
|
|
||||||
params.set("limit", String(limit));
|
|
||||||
params.set("sort", sort.value);
|
|
||||||
params.set("order", order.value);
|
|
||||||
if (search.value.trim()) params.set("q", search.value.trim());
|
|
||||||
if (selectedStatuses.value.length) params.set("status", selectedStatuses.value.join(","));
|
|
||||||
if (selectedPaises.value.length) params.set("pais", selectedPaises.value.join(","));
|
|
||||||
if (desde.value) params.set("desde", desde.value);
|
|
||||||
if (hasta.value) params.set("hasta", hasta.value);
|
|
||||||
if (edadMin.value) params.set("edad_min", edadMin.value);
|
|
||||||
if (edadMax.value) params.set("edad_max", edadMax.value);
|
|
||||||
for (const [f, v] of Object.entries(coreText)) if (v) params.set(f, v);
|
|
||||||
if (sexo.value) params.set("sexo", sexo.value);
|
|
||||||
if (nacionalidad.value) params.set("nacionalidad", nacionalidad.value);
|
|
||||||
if (formVersion.value) params.set("form_version", formVersion.value);
|
|
||||||
for (const f of responseFields) if (respFilters[f]) params.set(f, respFilters[f]);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await cachedFetch(`/api/admin/voluntarios?${params.toString()}`, { ttl: 30 });
|
|
||||||
const json = await res.json();
|
|
||||||
if (!json.success) throw new Error(json.message || "Error al cargar");
|
|
||||||
rows.value = json.data;
|
|
||||||
total.value = json.total;
|
|
||||||
totalPages.value = json.totalPages;
|
|
||||||
page.value = json.page;
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchOptions() {
|
|
||||||
try {
|
|
||||||
const res = await cachedFetch("/api/admin/voluntarios/options", { ttl: 300 });
|
|
||||||
const json = await res.json();
|
|
||||||
if (json.success) {
|
|
||||||
statuses.value = json.statuses;
|
|
||||||
formVersions.value = json.form_versions;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// opciones no críticas
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSearch() {
|
|
||||||
clearTimeout(searchTimer);
|
|
||||||
searchTimer = setTimeout(() => {
|
|
||||||
page.value = 1;
|
|
||||||
fetchData();
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyFilters() {
|
|
||||||
page.value = 1;
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearFilters() {
|
|
||||||
search.value = "";
|
|
||||||
selectedStatuses.value = [];
|
|
||||||
selectedPaises.value = [];
|
|
||||||
desde.value = "";
|
|
||||||
hasta.value = "";
|
|
||||||
edadMin.value = "";
|
|
||||||
edadMax.value = "";
|
|
||||||
Object.keys(coreText).forEach((k) => (coreText[k] = ""));
|
|
||||||
sexo.value = "";
|
|
||||||
nacionalidad.value = "";
|
|
||||||
formVersion.value = "";
|
|
||||||
Object.keys(respFilters).forEach((k) => (respFilters[k] = ""));
|
|
||||||
page.value = 1;
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSort(field) {
|
|
||||||
if (sort.value === field) {
|
|
||||||
order.value = order.value === "asc" ? "desc" : "asc";
|
|
||||||
} else {
|
|
||||||
sort.value = field;
|
|
||||||
order.value = "asc";
|
|
||||||
}
|
|
||||||
page.value = 1;
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function goPage(p) {
|
|
||||||
if (p < 1 || p > totalPages.value || p === page.value) return;
|
|
||||||
page.value = p;
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageNumbers = computed(() => {
|
|
||||||
const total = totalPages.value;
|
|
||||||
const current = page.value;
|
|
||||||
const start = Math.max(1, current - 2);
|
|
||||||
const end = Math.min(total, current + 2);
|
|
||||||
const pages = [];
|
|
||||||
for (let i = start; i <= end; i++) pages.push(i);
|
|
||||||
return pages;
|
|
||||||
});
|
|
||||||
|
|
||||||
function formatDate(iso) {
|
|
||||||
if (!iso) return "—";
|
|
||||||
return new Date(iso).toLocaleDateString("es", {
|
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function badgeClass(s) {
|
|
||||||
switch (s) {
|
|
||||||
case "aprobado":
|
|
||||||
return "badge-success";
|
|
||||||
case "rechazado":
|
|
||||||
return "badge-error";
|
|
||||||
case "legacy":
|
|
||||||
return "badge-warning";
|
|
||||||
default:
|
|
||||||
return "badge-neutral";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchOptions();
|
|
||||||
fetchData();
|
|
||||||
window.addEventListener("popstate", onPopstate);
|
|
||||||
window.addEventListener("keydown", onKeydown);
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener("popstate", onPopstate);
|
|
||||||
window.removeEventListener("keydown", onKeydown);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
@ -29,7 +29,7 @@ const imageUrl = props.image || ''
|
||||||
{ props.type === 'imgText' && (
|
{ props.type === 'imgText' && (
|
||||||
<div class={`flex flex-col justify-between h-full bg-[${props.bgColor}]`}>
|
<div class={`flex flex-col justify-between h-full bg-[${props.bgColor}]`}>
|
||||||
<div class="grid grid-cols-1 gap-0 p-8 font-bold">
|
<div class="grid grid-cols-1 gap-0 p-8 font-bold">
|
||||||
<div class="md:px-10 md:py-10">
|
<div class="px-12 py-10">
|
||||||
<Icon name={props.icon} class="text-3xl" />
|
<Icon name={props.icon} class="text-3xl" />
|
||||||
<p class={`font-primary text-xl text-[${textColor}]`}>{props.text}</p>
|
<p class={`font-primary text-xl text-[${textColor}]`}>{props.text}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,61 +2,32 @@
|
||||||
import { Image } from "astro:assets"
|
import { Image } from "astro:assets"
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import "dayjs/locale/es";
|
import "dayjs/locale/es";
|
||||||
import "dayjs/locale/fr";
|
|
||||||
import "dayjs/locale/he";
|
|
||||||
import "dayjs/locale/uk";
|
|
||||||
import "dayjs/locale/pt";
|
|
||||||
import "dayjs/locale/ru";
|
|
||||||
import "dayjs/locale/rw";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import { getLocalizedRoute, createTranslator } from "../../i18n";
|
const regionNames = new Intl.DisplayNames(['es'], { type: 'region' });
|
||||||
|
|
||||||
const locale = Astro.currentLocale || "es";
|
const locale = Astro.currentLocale;
|
||||||
const tl = createTranslator(locale);
|
|
||||||
const regionNames = new Intl.DisplayNames([locale], { type: 'region' });
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
dayjs.locale(locale);
|
dayjs.locale(locale);
|
||||||
|
|
||||||
const { data, routeKey = "news" } = Astro.props;
|
const { data } = Astro.props;
|
||||||
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
|
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
|
||||||
const countryName = data?.data?.country ? regionNames.of(data.data.country) : "";
|
const countryName = regionNames.of(data.data.country);
|
||||||
|
|
||||||
const locationArray = [data.data.city,countryName]
|
|
||||||
locationArray.filter(Boolean).join(', ');
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="bg-[#EBE5D0] text-[#003421] p-10">
|
<div class="bg-[#EBE5D0] text-[#003421] p-10">
|
||||||
<div class="flex md:flex-col items-center content-center md:items-baseline">
|
<Icon name="ph:arrow-circle-down-thin" class="text-8xl mb-8" />
|
||||||
<Icon name="ph:arrow-circle-down-thin" class="md:text-8xl text-7xl mb-0 md:mb-8" />
|
<p class="font-light text-2xl mb-8">
|
||||||
{nicedate ? (
|
{data.data.city}, {countryName}<br />({nicedate}):
|
||||||
<p class="font-light md:text-2xl text-lg ml-2 md:ml-0 md:mb-8 mb-3">
|
</p>
|
||||||
{locationArray.filter(Boolean).join(', ')}<br />
|
<h3 class="text-2xl font-bold mb-8"><a href={`/${locale}/news/${data.id}`}>{data.data.title}</a></h3>
|
||||||
({nicedate}):
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
<p class="font-light md:text-2xl text-lg md:mb-8 mb-3">
|
|
||||||
{locationArray.filter(Boolean).join(', ')}:
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<h3 class="md:text-2xl text-lg mb-4 font-bold md:mb-8 hover:underline"><a href={`/${locale}/${getLocalizedRoute(routeKey, locale)}/${data.data.slug}`}>{data.data.title}</a></h3>
|
|
||||||
|
|
||||||
<div class="overflow-hidden">
|
<div>
|
||||||
<a href={`/${locale}/${getLocalizedRoute(routeKey, locale)}/${data.data.slug}`}>
|
|
||||||
<Image
|
<Image
|
||||||
src={data.data.thumbnail}
|
src={data.data.thumbnail}
|
||||||
alt={data.data.title}
|
alt={data.data.title}
|
||||||
class="aspect-square object-cover transition-transform duration-300 hover:scale-110"
|
class="aspect-square object-cover"
|
||||||
/>
|
/>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-8">
|
|
||||||
<a href={`/${locale}/${getLocalizedRoute(routeKey, locale)}/${data.data.slug}`} class="inline-flex items-center gap-2 px-6 py-3 bg-white text-[#22523F] hover:bg-[#22523F] hover:text-[#EBE6D2] hover:underline font-bold transition text-sm rounded-none uppercase">
|
|
||||||
{tl(routeKey + ".fullnew")}
|
|
||||||
<Icon name="ph:arrow-right" class="transform group-hover:translate-x-1 transition-transform" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
import { Image } from "astro:assets";
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import "dayjs/locale/es";
|
|
||||||
import "dayjs/locale/fr";
|
|
||||||
import "dayjs/locale/he";
|
|
||||||
import "dayjs/locale/uk";
|
|
||||||
import "dayjs/locale/pt";
|
|
||||||
import "dayjs/locale/ru";
|
|
||||||
import "dayjs/locale/rw";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import utc from "dayjs/plugin/utc";
|
|
||||||
|
|
||||||
const locale = Astro.currentLocale || "es";
|
|
||||||
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
|
|
||||||
|
|
||||||
import { createTranslator, getLocalizedRoute } from "@/i18n";
|
|
||||||
const tl = createTranslator(locale);
|
|
||||||
dayjs.extend(utc);
|
|
||||||
dayjs.locale(locale);
|
|
||||||
|
|
||||||
const { data, content, routeKey = "news" } = Astro.props;
|
|
||||||
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
|
|
||||||
const countryName = data?.data?.country ? regionNames.of(data.data.country) : "";
|
|
||||||
|
|
||||||
const location = [data.data.city, data.data.state, countryName].filter(Boolean).join(", ");
|
|
||||||
|
|
||||||
const newsUrl = `/${locale}/${getLocalizedRoute(routeKey, locale)}/${data.data.slug}`;
|
|
||||||
|
|
||||||
const rawContent = content?.body || "";
|
|
||||||
const plainText = rawContent.replace(/^#.*$/gm, "").replace(/^###.*$/gm, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>.*$/gm, "").replace(/`[^`]+`/g, "").replace(/^[-*]\s+/gm, "").trim();
|
|
||||||
const words = plainText.split(/\s+/).filter((w) => w.length > 0).slice(0, 40);
|
|
||||||
const excerpt = words.join(" ") + (words.length === 40 ? "..." : "");
|
|
||||||
---
|
|
||||||
|
|
||||||
<a href={newsUrl} class="block group">
|
|
||||||
<article class="flex flex-col md:flex-row gap-6 md:gap-8 p-4 md:p-6 border-b border-tertiary/20 hover:bg-tertiary/5 transition-colors">
|
|
||||||
<div class="md:w-1/3 flex-shrink-0 overflow-hidden justify-center items-center flex">
|
|
||||||
<Image src={data.data.thumbnail_square || data.data.thumbnail} alt={data.data.title} width={480} class="w-full h-auto object-contain transform group-hover:scale-105 transition-transform duration-300" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md:w-2/3 flex flex-col">
|
|
||||||
<div class="flex items-center gap-2 mb-2">
|
|
||||||
<span class="font-normal font-primary text-sm text-tertiary/70">{nicedate}</span>
|
|
||||||
{location && <><span class="text-tertiary/40">|</span><span class="font-normal font-primary text-sm text-tertiary/70">{location}</span></>}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="text-xl md:text-2xl font-bold font-secondary text-tertiary group-hover:text-tertiary/80 transition-colors mb-2">{data.data.title}</h3>
|
|
||||||
|
|
||||||
<p class="font-primary text-base text-tertiary/80 mb-4 line-clamp-3">{excerpt}</p>
|
|
||||||
|
|
||||||
{data.data.tags && data.data.tags.length > 0 && (
|
|
||||||
<div class="flex flex-nowrap md:flex-wrap gap-2 overflow-x-auto md:overflow-visible pb-2 md:pb-0 mb-4">
|
|
||||||
{data.data.tags.map((tag: string) => (
|
|
||||||
<span class="badge rounded-none bg-[#EBE6D2] border-none text-[#003421] whitespace-nowrap">{tag}</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<span class="inline-flex items-center gap-1 text-sm font-primary text-tertiary font-semibold group-hover:underline">
|
|
||||||
{tl(routeKey + ".seemore")}
|
|
||||||
<Icon name="ph:arrow-right" class="transform group-hover:translate-x-1 transition-transform" />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</a>
|
|
||||||
|
|
@ -1,36 +1,30 @@
|
||||||
---
|
---
|
||||||
|
import { Image } from "astro:assets";
|
||||||
import "swiper/css";
|
import "swiper/css";
|
||||||
import "swiper/css/navigation";
|
import "swiper/css/navigation";
|
||||||
import "swiper/css/pagination";
|
import "swiper/css/pagination";
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
|
const { images, class: className } = Astro.props;
|
||||||
const isHebrew = Astro.currentLocale === "he";
|
|
||||||
const { images, class: className, imgClass } = Astro.props;
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class={`bg-white ${className || ''}`}>
|
<div class="bg-white">
|
||||||
<div class="mx-auto">
|
<div class="mx-auto">
|
||||||
<div class="swiper">
|
<div class="swiper lg:h-200 md:h-150 h-100">
|
||||||
<div class="swiper-wrapper">
|
<div class="swiper-wrapper">
|
||||||
{
|
{
|
||||||
images.map((image) => (
|
images.map((image) => (
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide h-full">
|
||||||
<div class="relative">
|
<div class="flex! h-full flex-col items-center justify-center relative">
|
||||||
{image.text && (
|
{image.text && (
|
||||||
<div class="uppercase lg:text-9xl md:text-5xl text-4xl text-white text-shadow-lg absolute inset-0 flex items-center justify-center font-secondary z-10">
|
<div class="uppercase lg:text-9xl md:text-5xl text-4xl text-white text-shadow-lg absolute font-secondary">
|
||||||
{image.text}
|
{image.text}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<img
|
<img
|
||||||
class={`w-full ${imgClass || ''}`}
|
class="w-full h-full object-cover object-center"
|
||||||
src={image.image}
|
src={image.image}
|
||||||
alt={image.text}
|
alt={image.text}
|
||||||
/>
|
/>
|
||||||
{image.text_alt && (
|
|
||||||
<div class="text-sm text-white px-4 py-2 italic bg-black/50 absolute bottom-2 right-2 rounded z-10">
|
|
||||||
{image.text_alt}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|
@ -42,28 +36,10 @@ const { images, class: className, imgClass } = Astro.props;
|
||||||
|
|
||||||
<!-- If we need navigation buttons -->
|
<!-- If we need navigation buttons -->
|
||||||
<div class="swiper-button-prev">
|
<div class="swiper-button-prev">
|
||||||
{
|
<Icon name="ph:arrow-circle-left-thin" class="text-white" />
|
||||||
isHebrew && (
|
|
||||||
<Icon name="ph:arrow-circle-right-thin" class="text-white" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!isHebrew && (
|
|
||||||
<Icon name="ph:arrow-circle-left-thin" class="text-white" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-button-next">
|
<div class="swiper-button-next">
|
||||||
{
|
<Icon name="ph:arrow-circle-right-thin" class="text-white" />
|
||||||
isHebrew && (
|
|
||||||
<Icon name="ph:arrow-circle-left-thin" class="text-white" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!isHebrew && (
|
|
||||||
<Icon name="ph:arrow-circle-right-thin" class="text-white" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,38 +7,38 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
const { props } = Astro.props;
|
const { props } = Astro.props;
|
||||||
---
|
---
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto">
|
||||||
<div class="grid md:grid-cols-2 min-w-0">
|
<div class="grid md:grid-cols-2 min-h-100">
|
||||||
<div class="bg-[#EBE5D0] p-6 md:p-12 lg:p-24 grid lg:grid-cols-2 min-w-0">
|
<div class="bg-[#EBE5D0] p-12 md:p-24 grid lg:grid-cols-2">
|
||||||
<div class="flex flex-col justify-between min-h-full min-w-0">
|
<div class="leftcol flex justify-between flex-col min-h-full">
|
||||||
<h2 class="text-3xl lg:text-2xl xl:text-3xl 2xl:text-5xl font-secondary text-tertiary font-bold wrap-break-word">{tl("values.justice.title")}</h2>
|
<h2 class="text-5xl font-secondary text-tertiary font-bold">{tl("values.justice.title")}</h2>
|
||||||
<p class="text-lg text-tertiary break-words">{tl("values.justice.text")}</p>
|
<p class="text-lg text-tertiary">{tl("values.justice.text")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-end justify-end min-h-full min-w-0 max-w-full">
|
<div class="rightcol flex justify-end align-bottom min-h-full ">
|
||||||
<Icon name="icon_justice_1" class="text-6xl md:text-9xl text-tertiary max-w-full h-auto" />
|
<Icon name="icon_justice_1" class="text-9xl text-tertiary self-end" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-tertiary p-6 md:p-12 lg:p-24 grid lg:grid-cols-2 min-w-0">
|
<div class="bg-tertiary p-12 md:p-24 grid lg:grid-cols-2">
|
||||||
<div class="flex flex-col justify-between min-h-full min-w-0 max-w-full">
|
<div class="leftcol flex justify-between flex-col min-h-full">
|
||||||
<h2 class="text-3xl lg:text-2xl xl:text-3xl 2xl:text-5xl font-secondary font-bold text-[#CBA16A] wrap-break-word">{tl("values.integrity.title")}</h2>
|
<h2 class="text-5xl font-secondary font-bold text-[#CBA16A]">{tl("values.integrity.title")}</h2>
|
||||||
<p class="text-[#CBA16A] text-lg break-words">{tl("values.integrity.text")}</p>
|
<p class="text-[#CBA16A] text-lg">{tl("values.integrity.text")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-end justify-end min-h-full min-w-0 max-w-full">
|
<div class="rightcol flex justify-end align-bottom min-h-full ">
|
||||||
<Icon name="icon_justice_2" class="text-[#EBE5D0] text-6xl md:text-9xl max-w-full h-auto" />
|
<Icon name="icon_justice_2" class="text-[#EBE5D0] text-9xl self-end" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid lg:grid-cols-3">
|
<div class="grid lg:grid-cols-3">
|
||||||
<div class="bg-tertiary p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square min-w-0">
|
<div class="bg-tertiary p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square">
|
||||||
<h2 class="text-3xl 2xl:text-5xl font-secondary font-bold text-white wrap-break-word">{tl("values.service.title")}</h2>
|
<h2 class="text-3xl xl:text-5xl font-secondary font-bold text-white">{tl("values.service.title")}</h2>
|
||||||
<p class="text-xl text-[#EBE5D0] wrap-break-word">{tl("values.service.text")}</p>
|
<p class="text-xl text-[#EBE5D0]">{tl("values.service.text")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-[#BEA48D] p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square min-w-0">
|
<div class="bg-[#BEA48D] p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square">
|
||||||
<h2 class="text-3xl 2xl:text-5xl font-secondary font-bold text-tertiary wrap-break-word">{tl("values.excellence.title")}</h2>
|
<h2 class="text-3xl xl:text-5xl font-secondary font-bold text-tertiary">{tl("values.excellence.title")}</h2>
|
||||||
<p class="text-xl text-tertiary wrap-break-word">{tl("values.excellence.text")}</p>
|
<p class="text-xl text-tertiary">{tl("values.excellence.text")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-[#22523F] p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square min-w-0">
|
<div class="bg-[#22523F] p-12 xl:p-20 2xl:p-24 flex justify-between flex-col min-h-full lg:aspect-square">
|
||||||
<h2 class="text-3xl 2xl:text-5xl font-secondary font-bold text-white wrap-break-word">{tl("values.dialogue.title")}</h2>
|
<h2 class="text-3xl xl:text-5xl font-secondary font-bold text-white">{tl("values.dialogue.title")}</h2>
|
||||||
<p class="text-white text-xl wrap-break-word">{tl("values.dialogue.text")}</p>
|
<p class="text-white text-xl">{tl("values.dialogue.text")}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
---
|
|
||||||
import { getCollection } from "astro:content";
|
|
||||||
import { Image } from "@unpic/astro";
|
|
||||||
import Button from "../ui/Button.astro";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import utc from "dayjs/plugin/utc";
|
|
||||||
import { createTranslator, getLocalizedRoute } from '../../i18n';
|
|
||||||
|
|
||||||
const currentLocale = Astro.currentLocale;
|
|
||||||
const tl = createTranslator(currentLocale);
|
|
||||||
|
|
||||||
const items = await getCollection("editorial", (post)=>{
|
|
||||||
return post.data.locale == currentLocale
|
|
||||||
});
|
|
||||||
|
|
||||||
const sorted = [...items]
|
|
||||||
.sort((a, b) => {
|
|
||||||
const dateDiff = new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
|
|
||||||
if (dateDiff !== 0) return dateDiff
|
|
||||||
return (a.data.order ?? 0) - (b.data.order ?? 0)
|
|
||||||
})
|
|
||||||
.slice(0, 6);
|
|
||||||
|
|
||||||
dayjs.extend(utc);
|
|
||||||
dayjs.locale(currentLocale || "es");
|
|
||||||
---
|
|
||||||
|
|
||||||
<div id="editorial" class="bg-[#EBE5D0] py-10 lg:py-14">
|
|
||||||
<div class="container mx-auto px-4 md:px-0 max-w-4xl">
|
|
||||||
<div class="flex flex-col items-center mb-8">
|
|
||||||
<h4 class="text-[#003421] text-2xl uppercase font-bold text-center font-primary">{tl("editorial.title")}</h4>
|
|
||||||
<h2 class="text-[#003421] text-3xl md:text-4xl font-bold text-center font-secondary mt-1">{tl("editorial.text")}</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divide-y divide-[#003421]/10">
|
|
||||||
{
|
|
||||||
sorted.map((item) => {
|
|
||||||
const date = dayjs.utc(item.data.date).format("D MMMM YYYY");
|
|
||||||
const url = `/${currentLocale}/${getLocalizedRoute("editorial", currentLocale)}/${item.data.slug}`;
|
|
||||||
const thumb = item.data.thumbnail_square || item.data.thumbnail;
|
|
||||||
return (
|
|
||||||
<a href={url} class="flex gap-5 py-5 group hover:bg-[#003421]/5 transition-colors -mx-3 px-3 rounded-sm">
|
|
||||||
<div class="w-20 h-20 md:w-24 md:h-24 shrink-0 overflow-hidden rounded-sm bg-[#003421]/10">
|
|
||||||
{thumb && (
|
|
||||||
<Image src={thumb} alt={item.data.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="min-w-0 flex-1">
|
|
||||||
<p class="text-sm md:text-base font-primary font-semibold text-[#22523F]">Dr. José Benjamín Pérez Matos</p>
|
|
||||||
<p class="text-sm text-[#003421]/50 font-primary mt-0.5">{date}</p>
|
|
||||||
<h3 class="text-base md:text-lg font-secondary font-bold text-[#003421] group-hover:text-[#003421]/60 transition-colors mt-1 leading-snug line-clamp-2">{item.data.title}</h3>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-center mt-8">
|
|
||||||
<Button class="px-6 py-2.5 uppercase text-sm" url={`/${currentLocale}/${getLocalizedRoute('editorial', currentLocale)}`} variant="primary" title={tl("editorial.buttonLable")} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -4,84 +4,37 @@ import { Image } from "astro:assets";
|
||||||
import jbp from "../../assets/DRJBP-1.webp";
|
import jbp from "../../assets/DRJBP-1.webp";
|
||||||
import FormContact from "./FormContact.vue";
|
import FormContact from "./FormContact.vue";
|
||||||
|
|
||||||
import { createTranslator, t } from "../../i18n";
|
import { createTranslator, t } from '../../i18n';
|
||||||
const tl = createTranslator(Astro.currentLocale);
|
const tl = createTranslator(Astro.currentLocale);
|
||||||
|
|
||||||
const isHebrew = Astro.currentLocale === "he";
|
|
||||||
const { hideContact } = Astro.props;
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div id="contact" class="bg-[#22523F]">
|
<div id="contact" class="bg-[#22523F]">
|
||||||
<div class="container mx-auto py-20 relative text-[#EBE5D0]">
|
<div class="container mx-auto py-20 relative text-[#EBE5D0]">
|
||||||
|
|
||||||
<div class="absolute bottom-0 right-0 w-80 hidden lg:block">
|
<div class="absolute bottom-0 right-0 w-80 hidden lg:block">
|
||||||
<Image src={jbp} alt="Centro del Reino de Paz y Justicia" />
|
<Image src={jbp} alt="Centro del Reino de Paz y Justicia" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4
|
<h4 class="text-lg text-center font-bold uppercase" set:html={tl("footer.title")}></h4>
|
||||||
class="text-lg text-center font-bold uppercase"
|
<h2 class="text-2xl lg:text-5xl text-center font-bold font-secondary my-8" set:html={tl("footer.subtitle")}>
|
||||||
set:html={tl("footer.title")}
|
|
||||||
>
|
|
||||||
</h4>
|
|
||||||
<h2
|
|
||||||
class="text-2xl lg:text-5xl text-center font-bold font-secondary my-8"
|
|
||||||
set:html={tl("footer.subtitle")}
|
|
||||||
>
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="px-12 lg:px-4 lg:w-2/5 mx-auto">
|
<div class="px-12 lg:px-4 lg:w-2/5 mx-auto">
|
||||||
|
|
||||||
<p class="text-lg font-light mb-10" set:html={tl("footer.text")}></p>
|
<p class="text-lg font-light mb-10" set:html={tl("footer.text")}></p>
|
||||||
<p class="text-lg font-regular">
|
|
||||||
{tl("footer.email")}
|
|
||||||
<!--email_off-->
|
|
||||||
<a
|
|
||||||
class="font-light hover:text-[#D4C7A1] transition-all hover:underline hover:underline-offset-4 hidden lg:block"
|
|
||||||
href="mailto:joseperez@centrodelreinodepazyjusticia.com"
|
|
||||||
>joseperez@centrodelreinodepazyjusticia.com</a
|
|
||||||
>
|
|
||||||
<!--/email_off-->
|
|
||||||
</p>
|
|
||||||
<!--email_off-->
|
|
||||||
<a
|
|
||||||
class="font-light hover:text-[#D4C7A1] transition-all hover:underline hover:underline-offset-4 block lg:hidden overflow-hidden overflow-ellipsis"
|
|
||||||
href="mailto:joseperez@centrodelreinodepazyjusticia.com"
|
|
||||||
>joseperez@centrodelreinodepazyjusticia.com</a
|
|
||||||
>
|
|
||||||
<!--/email_off-->
|
|
||||||
<p
|
|
||||||
class="text-lg font-light mb-10 break-words"
|
|
||||||
set:html={tl("footer.text2")}
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{!hideContact && <FormContact client:load locale={Astro.currentLocale} />}
|
<p class="text-lg font-light mb-10 break-words" set:html={tl("footer.text2")}></p>
|
||||||
|
|
||||||
|
<FormContact client:load locale ={Astro.currentLocale}/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="flex lg:justify-between mt-10 lg:mt-0 align-center justify-center">
|
||||||
class="flex lg:justify-between mt-10 lg:mt-0 align-center justify-center"
|
<p class="px-4 order-1 text-sm font-normal text-white lg:self-end text-center lg:text-left">
|
||||||
>
|
{tl("footer.reserved")}
|
||||||
{
|
</p>
|
||||||
!isHebrew && (
|
<img class="w-24 lg:order-1 z-10 pl-6 object-contain" src="/img/logo-metalico.webp" alt="Logo Metalico">
|
||||||
<p class="px-4 order-1 text-sm font-normal text-white lg:self-end text-center lg:text-left">
|
|
||||||
{tl("footer.reserved")}
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="flex items-center gap-3 lg:order-1 z-10 pl-6">
|
|
||||||
<img
|
|
||||||
class="w-24 object-contain"
|
|
||||||
src="/img/logo-metalico.webp"
|
|
||||||
alt="Logo Metalico"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
isHebrew && (
|
|
||||||
<p class="text-sm font-normal text-white text-center lg:text-left">
|
|
||||||
{tl("footer.reserved")}
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,28 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Icon } from "@iconify/vue";
|
import { Icon } from "@iconify/vue";
|
||||||
import { createTranslator } from "../../i18n";
|
import { createTranslator } from "../../i18n";
|
||||||
import { ref, computed } from "vue";
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
locale: String
|
locale: String
|
||||||
});
|
});
|
||||||
|
|
||||||
const tl = createTranslator(props.locale);
|
const tl = createTranslator(props.locale);
|
||||||
const isLoading = ref(false);
|
|
||||||
const isSuccess = ref(false);
|
|
||||||
const isError = ref(false);
|
|
||||||
|
|
||||||
const dashOffset = ref(453);
|
|
||||||
|
|
||||||
const dashStyle = computed(() => ({
|
|
||||||
stroke: "#1ecd97",
|
|
||||||
fill: "white",
|
|
||||||
strokeDasharray: 453,
|
|
||||||
strokeDashoffset: dashOffset.value,
|
|
||||||
transition: "stroke-dashoffset 1.2s ease"
|
|
||||||
}));
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
const formData = new FormData(e.target);
|
const formData = new FormData(e.target);
|
||||||
|
|
||||||
isLoading.value = true;
|
|
||||||
isSuccess.value = false;
|
|
||||||
isError.value = false;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/emailInfo/send", {
|
const response = await fetch("/api/emailInfo/send", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) throw new Error();
|
|
||||||
|
|
||||||
e.target.reset();
|
e.target.reset();
|
||||||
isSuccess.value = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
isSuccess.value = false;
|
|
||||||
}, 3500);
|
|
||||||
|
|
||||||
|
if (!response.ok)
|
||||||
|
throw new Error();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
isError.value = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
isError.value = false;
|
|
||||||
}, 3500);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
setTimeout(() => {
|
|
||||||
isLoading.value = false;
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -87,102 +55,48 @@ const handleSubmit = async (e) => {
|
||||||
:placeholder="tl('footer.form.mesagge')"
|
:placeholder="tl('footer.form.mesagge')"
|
||||||
rows="5"
|
rows="5"
|
||||||
required
|
required
|
||||||
class="bg-[#EBE5D0] w-full py-2 px-4 mb-2 text-[#303335] placeholder:text-[#303335] focus:outline-none resize-none"
|
class="bg-[#EBE5D0] w-full py-2 px-4 mb-2 text-[#303335] placeholder:text-[#303335] focus:outline-none"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<!-- Submit -->
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
:disabled="isLoading"
|
|
||||||
class="bg-[#003421] px-6 py-2 text-sm cursor-pointer transition duration-300"
|
|
||||||
:class="[
|
|
||||||
isLoading ? 'opacity-70 cursor-not-allowed' : 'hover:bg-[#EBE5D0] hover:text-[#003421]',
|
|
||||||
isError ? 'bg-red-600 text-white' : ''
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<span v-if="isLoading" class="flex items-center gap-2">
|
|
||||||
<span class="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></span>
|
|
||||||
Enviando...
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="isSuccess">
|
|
||||||
Enviado ✓
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="isError">
|
|
||||||
Error
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else>
|
|
||||||
{{ tl("footer.form.button") }}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="flex flex-row justify-between items-center mt-4">
|
<div class="flex flex-row justify-between items-center mt-4">
|
||||||
|
|
||||||
<!-- Social Icons -->
|
<!-- Social Icons -->
|
||||||
<ul class="flex flex-row gap-2">
|
<ul class="flex flex-row gap-2">
|
||||||
<li class="border-r pr-2">
|
<li class="border-r pr-2">
|
||||||
<a href="https://x.com/CRPazYJusticia" target="_blank">
|
<a href="https://x.com/CRPazYJusticia" target="_blank">
|
||||||
<Icon icon="ph:x-logo-thin" class="text-3xl hover:text-[#D4C7A1] transition-all hover:transform hover:scale-115" />
|
<Icon icon="ph:x-logo-thin" class="text-3xl" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="border-r pr-2">
|
<li class="border-r pr-2">
|
||||||
<a href="https://www.instagram.com/centrodelreinodepazyjusticia/" target="_blank">
|
<a href="https://www.instagram.com/centrodelreinodepazyjusticia/" target="_blank">
|
||||||
<Icon icon="ph:instagram-logo-thin" class="text-3xl hover:text-[#D4C7A1] transition-all hover:transform hover:scale-115" />
|
<Icon icon="ph:instagram-logo-thin" class="text-3xl" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="border-r pr-2">
|
<li class="border-r pr-2">
|
||||||
<a href="https://www.facebook.com/Centrodelreinodepazyjusticia" target="_blank">
|
<a href="https://www.facebook.com/Centrodelreinodepazyjusticia" target="_blank">
|
||||||
<Icon icon="ph:facebook-logo-thin" class="text-3xl hover:text-[#D4C7A1] transition-all hover:transform hover:scale-115" />
|
<Icon icon="ph:facebook-logo-thin" class="text-3xl" />
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="border-r pr-2">
|
|
||||||
<a href="https://www.youtube.com/@CentrodelReinodePazyJusticia" target="_blank">
|
|
||||||
<Icon icon="ph:youtube-logo-thin" class="text-3xl hover:text-[#D4C7A1] transition-all hover:transform hover:scale-115" />
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a href="https://t.me/CentroRPJ" target="_blank">
|
<a href="https://www.youtube.com/@CentrodelReinodePazyJusticia" target="_blank">
|
||||||
<Icon icon="ph:telegram-logo-thin" class="text-3xl hover:text-[#D4C7A1] transition-all hover:transform hover:scale-115" />
|
<Icon icon="ph:youtube-logo-thin" class="text-3xl" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- Submit -->
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="bg-[#003421] px-6 py-2 text-sm hover:bg-[#EBE5D0] hover:text-[#003421] cursor-pointer transition duration-300"
|
||||||
|
>
|
||||||
|
{{ tl("footer.form.button") }}
|
||||||
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.kk-submit {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-bg {
|
|
||||||
stroke: #c8c8c8;
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-color {
|
|
||||||
stroke-width: 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textNode {
|
|
||||||
fill: #48727F;
|
|
||||||
font-family: 'Montserrat', sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkNode {
|
|
||||||
fill: #1ecd97;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -10,37 +10,37 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<h2 class="text-3xl lg:text-5xl text-center font-bold font-secondary my-8 text-[#003421]">{tl("formation.title")}</h2>
|
<h2 class="text-3xl lg:text-5xl text-center font-bold font-secondary my-8 text-[#003421]">{tl("formation.title")}</h2>
|
||||||
<p class="text-lg w-2/3 mx-auto mb-20 text-[#003421] text-justify" set:html={tl("formation.text")}></p>
|
<p class="text-lg w-2/3 mx-auto mb-20 text-[#003421] text-justify" set:html={tl("formation.text")}></p>
|
||||||
|
|
||||||
<div class="grid xl:grid-cols-3 text-[#003421] md:gap-20 gap-10 md:p-0 p-5">
|
<div class="grid xl:grid-cols-3 text-[#003421] gap-20">
|
||||||
<div class="bg-[#EBE5D0] p-12 relative pb-32 md:pb-52">
|
<div class="bg-[#EBE5D0] p-12 relative pb-40">
|
||||||
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
||||||
<h4 class="text-[#003421] text-2xl mb-12">{tl("formation.area.title")}</h4>
|
<h4 class="text-[#003421] text-2xl mb-12">{tl("formation.area.title")}</h4>
|
||||||
|
|
||||||
<ul class="text-lg list-disc font-normal list-inside leading-8" set:html={tl("formation.area.text")}></ul>
|
<ul class="text-lg list-disc font-normal list-inside leading-8" set:html={tl("formation.area.text")}></ul>
|
||||||
|
|
||||||
<div class="bottom-8 right-8 md:bottom-12 md:right-12 absolute">
|
<div class="bottom-12 right-12 absolute">
|
||||||
<Icon name="icon_formation_1" class="text-8xl md:text-9xl text-[#003421]" />
|
<Icon name="icon_formation_1" class="text-8xl text-[#003421]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-[#EBE5D0] p-12 relative pb-32 md:pb-52">
|
<div class="bg-[#EBE5D0] text-[#003421] p-12 relative pb-40">
|
||||||
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
||||||
<h4 class="text-[#003421] text-2xl mb-12">{tl("formation.consulting.title")}</h4>
|
<h4 class="text-[#003421] text-2xl mb-12">{tl("formation.consulting.title")}</h4>
|
||||||
|
|
||||||
<p class="text-lg font-normal">{tl("formation.consulting.text")}</p>
|
<p class="text-lg font-normal">{tl("formation.consulting.text")}</p>
|
||||||
|
|
||||||
<div class="bottom-8 right-8 md:bottom-12 md:right-12 absolute">
|
<div class="bottom-12 right-12 absolute">
|
||||||
<Icon name="icon_formation_2" class="text-8xl md:text-9xl text-[#003421]" />
|
<Icon name="icon_formation_2" class="text-8xl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-[#EBE5D0] p-12 relative pb-32 md:pb-52">
|
<div class="bg-[#EBE5D0] text-[#003421] p-12 relative pb-40">
|
||||||
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
<Icon name="ph:arrow-circle-down-thin" class="text-6xl mb-12 text-[#003421]" />
|
||||||
<h4 class="text-[#003421] text-2xl mb-12" set:html={tl("formation.action.title")}></h4>
|
<h4 class="text-[#003421] text-2xl mb-12" set:html={tl("formation.action.title")}></h4>
|
||||||
|
|
||||||
<p class="text-lg font-normal" set:html={tl("formation.action.text")}></p>
|
<p class="text-lg font-normal" set:html={tl("formation.action.text")}></p>
|
||||||
|
|
||||||
<div class="bottom-8 right-8 md:bottom-12 md:right-12 absolute">
|
<div class="bottom-12 right-12 absolute">
|
||||||
<Icon name="icon_formation_3" class="text-8xl md:text-9xl text-[#003421]" />
|
<Icon name="icon_formation_3" class="text-8xl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const cards = [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
icon: 'ph:arrow-circle-up-thin',
|
icon: 'ph:arrow-circle-up-thin',
|
||||||
text: 'Enseñanza de las escrituras aplicada al análisis del mundo contemporáneo.',
|
text: 'Enseñanza bíblica aplicada al análisis del mundo contemporáneo.',
|
||||||
textColor: '#EBE5D0',
|
textColor: '#EBE5D0',
|
||||||
bgColor: '#003421'
|
bgColor: '#003421'
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<div id="somos" class="container mx-auto">
|
<div id="somos" class="container mx-auto">
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 bg-white">
|
<div class="grid grid-cols-1 md:grid-cols-3 bg-white">
|
||||||
<div class="bg-[#22523F] col-span-1 flex items-center justify-center bg-[url('/img/opacity-logo.png')] bg-cover bg-no-repeat bg-right md:bg-left">
|
<div class="bg-[#22523F] col-span-1 flex items-center justify-center bg-[url('/src/assets/mid-logo-2.webp')] bg-no-repeat bg-right md:bg-left">
|
||||||
<img src="/img/logo-metalico.webp" alt="" class="w-1/4 my-8 md:w-1/2" />
|
<img src="/img/logo-metalico.webp" alt="" class="w-1/4 my-8 md:w-1/2" />
|
||||||
</div>
|
</div>
|
||||||
<div class={`flex flex-col text-tertiary col-span-2 gap-8 py-8 md:py-16 lg:py-24 px-8 sm:px-16 lg:px-32`}>
|
<div class={`flex flex-col text-tertiary col-span-2 gap-8 py-8 md:py-16 lg:py-24 px-8 sm:px-16 lg:px-32`}>
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<div class="col-span-1 h-full bg-[#CBA16A]">
|
<div class="col-span-1 h-full bg-[#CBA16A]">
|
||||||
<BoxContainer props={tl("info.endbox")} />
|
<BoxContainer props={tl("info.endbox")} />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-1 py-10 lg:px-24 bg-[#21523F]">
|
<div class="col-span-1 py-38 lg:px-24 bg-[#21523F]">
|
||||||
<img src="/img/logo-new-white.png" alt="Logo del Centro del Reino de Paz y Justicia (CRPJ)" class="w-1/3 lg:w-100 mx-auto">
|
<img src="/img/logo-ligth.webp" alt="Logo del Centro del Reino de Paz y Justicia (CRPJ)" class="w-1/3 lg:w-100 mx-auto">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,31 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection, getEntry } from "astro:content";
|
||||||
import NewsCard from "../cards/NewsCard.astro";
|
import NewsCard from "../cards/NewsCard.astro";
|
||||||
import Button from "../ui/Button.astro";
|
const newsItems = await getCollection("news", (post)=>{
|
||||||
|
const currentLocale = Astro.currentLocale;
|
||||||
const { routeKey = "news", anchorId = "news", titlePrefix = "news" } = Astro.props;
|
|
||||||
const currentLocale = Astro.currentLocale;
|
|
||||||
|
|
||||||
const items = await getCollection(routeKey, (post)=>{
|
|
||||||
return post.data.locale == currentLocale
|
return post.data.locale == currentLocale
|
||||||
});
|
});
|
||||||
import { createTranslator, getLocalizedRoute } from '../../i18n';
|
|
||||||
|
import { createTranslator, t } from '../../i18n';
|
||||||
const tl = createTranslator(Astro.currentLocale);
|
const tl = createTranslator(Astro.currentLocale);
|
||||||
---
|
---
|
||||||
<div id={anchorId} class="bg-[#22523F] py-12 lg:py-20">
|
<div id="news" class="bg-[#22523F] py-12 lg:py-20">
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto">
|
||||||
<div class="flex flex-col lg:w-1/2 items-center mx-auto py-8">
|
<div class="flex flex-col lg:w-1/2 items-center mx-auto py-8">
|
||||||
<h4 class="text-white text-2xl uppercase font-bold text-center mb-4 font-primary">{tl(titlePrefix + ".title")}</h4>
|
<h4 class="text-white text-2xl uppercase font-bold text-center mb-4 font-primary">{tl("news.title")}</h4>
|
||||||
<h2 class="text-white text-3xl lg:text-5xl font-bold text-center font-secondary mb-4">{tl(titlePrefix + ".text")}</h2>
|
<h2 class="text-white text-3xl lg:text-5xl font-bold text-center font-secondary mb-4">{tl("news.text")}</h2>
|
||||||
<p class="text-white text-xl text-center">{tl(titlePrefix + ".text2")}</p>
|
<p class="text-white text-xl text-center">{tl("news.text2")}</p>
|
||||||
<Button class="px-6 py-3 uppercase mt-4" url={`/${currentLocale}/${getLocalizedRoute(routeKey, currentLocale)}`} variant="primary" title={tl(titlePrefix + ".buttonLable")} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 md:gap-10 gap-20">
|
<div class="grid md:grid-cols-2 lg:grid-cols-3 md:gap-10 gap-20">
|
||||||
{
|
{
|
||||||
[...items]
|
[...newsItems] // copiamos para no mutar el original
|
||||||
.sort((a, b) => {
|
.sort((a, b) =>
|
||||||
const dateDiff =
|
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
|
||||||
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
|
)
|
||||||
|
|
||||||
if (dateDiff !== 0) return dateDiff
|
|
||||||
|
|
||||||
return (a.data.order ?? 0) - (b.data.order ?? 0)
|
|
||||||
})
|
|
||||||
.slice(0,6)
|
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<NewsCard data={item} routeKey={routeKey} />
|
<NewsCard data={item} />
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ const tl = createTranslator(Astro.currentLocale);
|
||||||
<div class="hidden lg:block row-span-2 col-span-full lg:col-span-1 over bg-[#CBA16A] relative">
|
<div class="hidden lg:block row-span-2 col-span-full lg:col-span-1 over bg-[#CBA16A] relative">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<BoxContainer props={{
|
<BoxContainer props={{
|
||||||
bgImage: 'https://ik.imagekit.io/crpy/tr:o-20/white-lion.png',
|
bgImage: 'https://ik.imagekit.io/crpy/tr:o-20/dove.webp?updatedAt=1770966556158',
|
||||||
bgColor: '#CBA16A',
|
bgColor: '#CBA16A',
|
||||||
}} />
|
}} />
|
||||||
<div class="absolute -bottom-[8rem] z-10 w-full">
|
<div class="absolute -bottom-[8rem] z-10 w-full">
|
||||||
<img src="/img/logo-new-white.png" class="w-1/2 mx-auto" alt="Logo del Centro del Reino de Paz y Justicia (CRPJ)">
|
<img src="/img/logo-ligth.webp" class="w-1/2 mx-auto" alt="Logo del Centro del Reino de Paz y Justicia (CRPJ)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden lg:flex bg-[#22523F] object-cover pt-64 justify-end ">
|
<div class="hidden lg:flex bg-[#22523F] object-cover pt-64 justify-end ">
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ import { Icon } from 'astro-icon/components'
|
||||||
|
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
---
|
---
|
||||||
<div class="md:py-16 p-4 bg-white">
|
<div class="py-16 bg-white">
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto">
|
||||||
<div class="flex justify-between px-4 align-center items-center">
|
<div class="flex justify-between px-4">
|
||||||
<h2 id="article-title" class="text-tertiary font-secondary text-xl sm:text-2xl md:text-3xl lg:text-5xl font-bold">{title}</h2>
|
<h2 class="text-tertiary font-secondary text-xl sm:text-2xl md:text-3xl lg:text-5xl font-bold">{title}</h2>
|
||||||
<img class="md:w-20 md:h-20 w-10 h-10" src="/img/lion.svg" alt="Leon">
|
<Icon name="logo" class="text-6xl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3,57 +3,23 @@ import { glob, file } from 'astro/loaders';
|
||||||
import { z } from 'astro/zod';
|
import { z } from 'astro/zod';
|
||||||
|
|
||||||
const news = defineCollection({
|
const news = defineCollection({
|
||||||
loader: glob({
|
loader: glob({ pattern: "**/*.md", base: "./src/content/news" }),
|
||||||
pattern: "**/*.md",
|
|
||||||
base: "./src/content/news",
|
|
||||||
generateId: ({ data, entry }) => `${data.locale}/${data.slug ?? entry.replace(/\.md$/, "")}`,
|
|
||||||
}),
|
|
||||||
schema: ({ image }) => z.object({
|
schema: ({ image }) => z.object({
|
||||||
locale: z.string().describe("News main language"),
|
locale: z.string().describe("News main language"),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
slug: z.string(),
|
|
||||||
date: z.date(),
|
date: z.date(),
|
||||||
draft: z.boolean().optional(),
|
draft: z.boolean().optional(),
|
||||||
place: z.string().optional(),
|
place: z.string().optional(),
|
||||||
order: z.number().optional(),
|
|
||||||
city: z.string().optional(),
|
city: z.string().optional(),
|
||||||
state: z.string().optional(),
|
state: z.string().optional(),
|
||||||
country: z.string().optional(),
|
country: z.string().optional(),
|
||||||
thumbnail: image().optional().describe("Main news thumbnail image"),
|
thumbnail: image().optional().describe("Main news thumbnail image"),
|
||||||
thumbnail_square: image().optional().describe("Main news thumbnail square image"),
|
|
||||||
youtube: z.string().optional(),
|
youtube: z.string().optional(),
|
||||||
tags: z.array(z.string()).optional().describe("News tags"),
|
|
||||||
gallery: z.array(z.object({
|
gallery: z.array(z.object({
|
||||||
image: image().optional(),
|
image: image().optional(),
|
||||||
text: z.string().optional(),
|
text: z.string().optional()
|
||||||
text_alt: z.string().optional(),
|
|
||||||
})).optional().nullable()
|
})).optional().nullable()
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const editorial = defineCollection({
|
export const collections = { news };
|
||||||
loader: glob({ pattern: "**/*.md", base: "./src/content/editorial" }),
|
|
||||||
schema: ({ image }) => z.object({
|
|
||||||
locale: z.string().describe("Editorial main language"),
|
|
||||||
title: z.string(),
|
|
||||||
slug: z.string(),
|
|
||||||
date: z.date(),
|
|
||||||
draft: z.boolean().optional(),
|
|
||||||
place: z.string().optional(),
|
|
||||||
order: z.number().optional(),
|
|
||||||
city: z.string().optional(),
|
|
||||||
state: z.string().optional(),
|
|
||||||
country: z.string().optional(),
|
|
||||||
thumbnail: image().optional().describe("Main editorial thumbnail image"),
|
|
||||||
thumbnail_square: image().optional().describe("Main editorial thumbnail square image"),
|
|
||||||
youtube: z.string().optional(),
|
|
||||||
tags: z.array(z.string()).optional().describe("Editorial tags"),
|
|
||||||
gallery: z.array(z.object({
|
|
||||||
image: image().optional(),
|
|
||||||
text: z.string().optional(),
|
|
||||||
text_alt: z.string().optional(),
|
|
||||||
})).optional().nullable()
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { news, editorial };
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
import { defineCollection } from 'astro:content';
|
|
||||||
import { glob, file } from 'astro/loaders';
|
|
||||||
import { z } from 'astro/zod';
|
|
||||||
|
|
||||||
const news = defineCollection({
|
|
||||||
//loader: glob({ pattern: "**/*.md", base: "./src/content/news" }),
|
|
||||||
loader: async () => {
|
|
||||||
const response = await fetch("http://localhost:3000/api/news?depth=1&draft=false&locale=es&trash=false");
|
|
||||||
const rawData = await response.json();
|
|
||||||
|
|
||||||
return rawData.docs.map((item: any) => {
|
|
||||||
item.id = item.id.toString()
|
|
||||||
return item
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
schema: ({ image }) => z.object({
|
|
||||||
locale: z.string().describe("News main language"),
|
|
||||||
title: z.string(),
|
|
||||||
date: z.string(),
|
|
||||||
slug: z.string(),
|
|
||||||
draft: z.boolean().optional().nullable(),
|
|
||||||
place: z.string().optional().nullable(),
|
|
||||||
order: z.number().optional().nullable(),
|
|
||||||
city: z.string().optional().nullable(),
|
|
||||||
state: z.string().optional().nullable(),
|
|
||||||
country: z.string().optional().nullable(),
|
|
||||||
thumbnail: z.object({
|
|
||||||
image: image().optional().nullable(),
|
|
||||||
url: z.string().optional().nullable()
|
|
||||||
}).optional().nullable().describe("Main news thumbnail image"),
|
|
||||||
//thumbnail_square: image().optional().describe("Main news thumbnail square image"),
|
|
||||||
youtube: z.string().optional(),
|
|
||||||
tags: z.array(z.string()).optional().describe("News tags"),
|
|
||||||
gallery: z.array(z.object({
|
|
||||||
image: z.object({
|
|
||||||
url: z.string().optional().nullable()
|
|
||||||
}).optional().nullable()
|
|
||||||
})).optional().nullable(),
|
|
||||||
body: z.string().nullable().optional()
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const editorial = defineCollection({
|
|
||||||
loader: glob({ pattern: "**/*.md", base: "./src/content/editorial" }),
|
|
||||||
schema: ({ image }) => z.object({
|
|
||||||
locale: z.string().describe("Editorial main language"),
|
|
||||||
title: z.string(),
|
|
||||||
date: z.date(),
|
|
||||||
slug: z.string(),
|
|
||||||
draft: z.boolean().optional(),
|
|
||||||
place: z.string().optional(),
|
|
||||||
order: z.number().optional(),
|
|
||||||
city: z.string().optional(),
|
|
||||||
state: z.string().optional(),
|
|
||||||
country: z.string().optional(),
|
|
||||||
thumbnail: image().optional().describe("Main editorial thumbnail image"),
|
|
||||||
thumbnail_square: image().optional().describe("Main editorial thumbnail square image"),
|
|
||||||
youtube: z.string().optional(),
|
|
||||||
tags: z.array(z.string()).optional().describe("Editorial tags"),
|
|
||||||
gallery: z.array(z.object({
|
|
||||||
image: image().optional(),
|
|
||||||
text: z.string().optional(),
|
|
||||||
text_alt: z.string().optional(),
|
|
||||||
})).optional().nullable()
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { news, editorial };
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'The True Nature of Ideas'
|
|
||||||
date: 2026-06-29
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-06-29-the-true-nature-of-ideas
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# The True Nature of Ideas
|
|
||||||
|
|
||||||
Election campaigns are often filled with promises, slogans, and carefully crafted speeches designed to win the citizens’ vote. However, once the political race is over, the moment comes when ideas leave the theoretical realm and begin to manifest themselves in reality. I firmly believe that the true nature of an ideology can be discerned precisely at that moment: not by what it promises, but by the behavior it inspires in its leaders, its supporters, and those who act on its behalf.
|
|
||||||
|
|
||||||
Ideologies should not be judged by the beauty of their rhetoric, but by their concrete results.
|
|
||||||
|
|
||||||
From this perspective, one of the clearest indicators is to observe how different political sectors react when they lose power or when the outcome of an election is unfavorable to them. In various Latin American countries—such as Chile, Bolivia, Honduras, and Ecuador—a frequently recurring phenomenon can be observed: when a left-wing government is replaced by a right-wing one, the response is not institutional acceptance, but rather unrest, riots, and actions aimed at disrupting public order. In contrast, when election results favor the left, normality prevails. The vast majority of the right accepts the results and respects order without resorting to violence as a tool of political pressure; the few isolated incidents of unrest stem from reckless individuals or provocateurs infiltrated to sow destabilization.
|
|
||||||
|
|
||||||
This profound difference and moral asymmetry is clearly evident in the security measures surrounding leaders during political races.
|
|
||||||
|
|
||||||
I remember perfectly well the harsh criticism directed at the Colombian president for attending his rallies surrounded by strict security measures and armored protection, which was used to portray him as someone who was afraid. However, that leader had to protect his life because there were specific death threats against him. In contrast, the left-wing candidate walked freely and without fear. The explanation is purely logical: his supporters would never attack their own leader, and those of us on the right are not murderers, nor do we use the physical elimination of our adversaries as a tool of political action. It is in this need for protection that it becomes clear which side harbors a propensity for harm and evil.
|
|
||||||
|
|
||||||
This is not about making absolute generalizations; I recognize that not everyone who identifies with the left engages in such behavior. Many citizens support these movements in good faith, convinced that they represent a path toward a more just society. However, they are misled by ideological positions that promise social justice, but they are completely unaware of their real consequences.
|
|
||||||
|
|
||||||
The examples in the region are painful, obvious, and indisputable.
|
|
||||||
|
|
||||||
Cuba, which was once one of the most prosperous and advanced islands in the continent, is now sinking into deep economic and social decline, lacking even basic services such as electricity. Nicaragua and Venezuela have followed the same path of institutional and economic destruction.
|
|
||||||
|
|
||||||
This latter nation is currently undergoing a crucial transition; and it is my fervent hope that this process may come to full completion so that the Venezuelan people may break their chains, restore their democratic institutions, and once again live in absolute and total freedom.
|
|
||||||
|
|
||||||
Recent history provides ample examples with which to evaluate each model; therefore, I reaffirm my conviction that the defense of freedom, the Rule of Law, and peaceful coexistence are the indispensable pillars for building truly prosperous societies.
|
|
||||||
|
|
||||||
**Dr. José Benjamín Pérez Matos**<br>
|
|
||||||
President<br>
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Temporary Peace or the Beginning of a Global Realignment in the Middle East?'
|
|
||||||
date: 2026-07-26
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-07-26-temporary-peace-or-the-beginning-of-a-global-realignment-in-the-middle-east
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# Temporary Peace or the Beginning of a Global Realignment in the Middle East?
|
|
||||||
|
|
||||||
The events of recent weeks in the Middle East have once again placed the region at the center of international attention. The recent pause in U.S. bombings on Iranian territory, after nearly two weeks of continuous hostilities, has opened a waiting period that many analysts are presenting as a possible step toward an instance of strategic diplomacy.
|
|
||||||
The technical talks held in Oman and the efforts aimed at stabilizing transit through the Strait of Hormuz, appear to reflect the intention to reduce tension and avoid an escalation that would further jeopardize regional stability and international trade.
|
|
||||||
|
|
||||||
However, for **Dr. José Benjamín Pérez Matos**, behind these diplomatic efforts lies a much deeper and more transcendent reality that cannot be understood solely from the perspective of international politics.
|
|
||||||
|
|
||||||
Referring to the moment the region is going through, he stated:
|
|
||||||
|
|
||||||
**"Now, these days, the United States is still at war with Iran; and the latest thing I heard: it seems they are going to leave it at that, when they should completely exterminate the problem at its root! If they keep dropping a couple of little bombs and then withdraw, later on they will do the same thing. See? These are seemingly temporary peace processes, but evil remains there."**
|
|
||||||
|
|
||||||
These words invite us to distinguish between a circumstantial peace and the definitive elimination of the causes that give rise to the conflict. From this perspective, a temporary interruption of military operations does not necessarily constitute the resolution of the problem, but merely a pause within a process that still remains open.
|
|
||||||
|
|
||||||
The very evolution of international events confirms the fragility of the current scenario.
|
|
||||||
|
|
||||||
While the United States military suspended its airstrikes after 13 consecutive nights of bombings, uncertainty continues to prevail in the international community. The outlook remains open, and the major powers continue to evaluate their next steps in a region whose stability remains decisive for the global geopolitical balance.
|
|
||||||
|
|
||||||
In this context, the President of the United States, Donald Trump, has maintained a position that combines diplomatic pressure with the possibility of reaching an understanding with Tehran.
|
|
||||||
|
|
||||||
On the one hand, he has issued severe warnings to the Iranian regime; on the other, he has publicly fueled expectations of a negotiation; stating, before the media gathered in the Oval Office:
|
|
||||||
|
|
||||||
“We can negotiate with them, which we’re also doing right now.”
|
|
||||||
|
|
||||||
However, the president himself also tempered those expectations by stating that he does not believe Iran is “ready” yet to reach a final agreement.
|
|
||||||
|
|
||||||
At the same time, he acknowledged:
|
|
||||||
|
|
||||||
“I think they’re getting more and more serious as the days go by, for maybe the obvious reason.”
|
|
||||||
|
|
||||||
The statements of the U.S. president reflect a scenario in which military pressure, diplomatic negotiation, and uncertainty over the definitive outcome of the conflict continue to coexist.
|
|
||||||
|
|
||||||
## The Prophetic Background of the Crisis
|
|
||||||
|
|
||||||
For **Dr. José Benjamín Pérez Matos**, fully understanding what is taking place between Washington and Tehran requires looking beyond a simple journalistic account and analyzing events from a broader perspective.
|
|
||||||
|
|
||||||
In this regard, he maintained that it is necessary to observe the geopolitical map through the lens of the biblical prophecies contained in chapter 2 of the book of Daniel.
|
|
||||||
|
|
||||||
In that context, he stated:
|
|
||||||
|
|
||||||
**“That kingdom of Persia, that kingdom of Iran, must be completely removed, so that only the kingdom of Rome remains; that is, the kingdom of the feet of iron and clay.”**
|
|
||||||
|
|
||||||
From this theological perspective, the final world order does not contemplate the coexistence of different geopolitical blocs developing simultaneously as parallel structures of power.
|
|
||||||
|
|
||||||
As **Dr. José Benjamín Pérez Matos** explained:
|
|
||||||
|
|
||||||
**"There can't also be a kingdom running parallel to that last kingdom of the legs of iron and clay; only that one must remain. Therefore, those remnants that remain of that Persian empire: Iran, must be removed. And that will be a very great sign when it happens. Which will mark a definitive prophetic milestone in these days."**
|
|
||||||
|
|
||||||
From this interpretation, current events transcend the strictly political and military realm, to become part of a broader historical process whose development, according to **Dr. José Benjamín Pérez Matos**, forms part of the progressive fulfillment of biblical prophecies.
|
|
||||||
|
|
||||||
## High-Pressure Diplomacy at the White House
|
|
||||||
|
|
||||||
It is precisely in this scenario of maximum tension that the visit of the Prime Minister of the State of Israel, Benjamin Netanyahu, to the United States takes on particular relevance.
|
|
||||||
|
|
||||||
Although the official reason for the trip is to participate in the funeral services of the late Senator Lindsey Graham —described by the Prime Minister’s Office as “a friend of Israel”— the scheduled meetings between the highest authorities of both countries will focus on the immediate future of the Middle East and the strategic challenges facing the region.
|
|
||||||
|
|
||||||
Referring to these meetings, **Dr. José Benjamín Pérez Matos** stated:
|
|
||||||
|
|
||||||
**"Now, we hope that... They have a meeting these days in Washington, or in New York. The Prime Minister of Israel, Benjamin Netanyahu, is going to be there, and they are going to talk about all of that as well."**
|
|
||||||
|
|
||||||
The importance of these conversations lies in the fact that Israel has cautiously observed the development of the U.S. attacks, fully aware that this crisis involves control of a strategic maritime route through which approximately twenty percent of the oil traded in the world passes.
|
|
||||||
|
|
||||||
Consequently, the reactivation of bilateral contacts between Washington and Jerusalem seeks to align stances against a common enemy and coordinate the next strategic steps in a scenario marked by the ongoing volatility of the Persian Gulf.
|
|
||||||
|
|
||||||
## The Race Against the Electoral Clock
|
|
||||||
|
|
||||||
In addition to the military and diplomatic components, the time factor appears as one of the most sensitive elements of the current situation.
|
|
||||||
|
|
||||||
The proximity of upcoming electoral processes introduces a political variable that could significantly modify the geopolitical scenario.
|
|
||||||
|
|
||||||
Domestically in the United States, President Donald Trump has downplayed speculation regarding the potential electoral impact of rising fuel prices.
|
|
||||||
|
|
||||||
Before the press, he stated:
|
|
||||||
|
|
||||||
“Despite what everyone says about the election, I’m not in a hurry… Elections take care of themselves.”
|
|
||||||
|
|
||||||
However, **Dr. José Benjamín Pérez Matos** drew attention to another electoral process that, from his perspective, is of even greater importance for the immediate future of the Middle East: the elections scheduled in Israel.
|
|
||||||
|
|
||||||
On this point, he said:
|
|
||||||
|
|
||||||
**“But look at what is happening in Israel: now there are going to be elections in October. They have to hurry. Because if a prime minister comes along who is not in favor (and aligned with that line of thought) of the religious world, of the Orthodox, and someone else comes along and wins the elections in October, things are going to get difficult for Israel. In other words, they should instead take advantage of the time remaining in his term, just in case there is a surprise in October.”**
|
|
||||||
|
|
||||||
These words reflect the importance that **Dr. José Benjamín Pérez Matos** attributes to the Israeli political calendar within the regional context. From this perspective, the time available to consolidate certain strategic decisions is limited and could be conditioned by the outcome of the upcoming elections.
|
|
||||||
|
|
||||||
As **Dr. José Benjamín Pérez Matos** himself noted: “The window to consolidate positions of strength is extremely narrow. Political actors must act swiftly in the face of the possibility of an electoral reversal or a surprise at the polls.”
|
|
||||||
|
|
||||||
This warning constitutes the natural conclusion of the geopolitical analysis developed throughout this reflection. However, for **Dr. José Benjamín Pérez Matos**, international events cannot be understood solely from the perspective of human decisions, diplomacy, or military strategy.
|
|
||||||
|
|
||||||
Above all those factors, there exists a higher purpose whose fulfillment, he states, continues to unfold according to the prophetic program revealed in the Scriptures.
|
|
||||||
|
|
||||||
For this reason, he concluded his statement with a reminder:
|
|
||||||
|
|
||||||
**“But remember that everything is, and everything will be fulfilled, according to the prophecies. None of this rests in human hands.”**
|
|
||||||
|
|
||||||
From the perspective presented by **Dr. José Benjamín Pérez Matos**, the events currently unfolding in the Middle East transcend the international situation and constitute part of a broader historical process. Beyond diplomatic negotiations, military decisions, or political changes that may occur in the various countries involved, the definitive outcome will be determined by the fulfillment of the prophetic purpose which, according to the Scriptures, will lead to the establishment of the final order announced in the book of Daniel.
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
locale: es
|
|
||||||
title: 'La verdadera naturaleza de las ideas'
|
|
||||||
date: 2026-06-29
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-06-29-la-verdadera-naturaleza-de-las-ideas
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# La verdadera naturaleza de las ideas
|
|
||||||
|
|
||||||
Las campañas electorales suelen estar cargadas de promesas, consignas y discursos cuidadosamente elaborados para conquistar el voto ciudadano. Sin embargo, una vez finalizada la contienda política, llega el momento en que las ideas abandonan el plano teórico y comienzan a manifestarse en la realidad. Sostengo firmemente que es precisamente en ese momento cuando resulta posible conocer la verdadera naturaleza de una ideología: no por lo que promete, sino por la conducta que inspira en sus dirigentes, en sus militantes y en quienes actúan en su nombre.
|
|
||||||
|
|
||||||
Las ideologías no deben ser juzgadas por la belleza de sus discursos, sino por sus resultados concretos.
|
|
||||||
|
|
||||||
Desde esta perspectiva, uno de los indicadores más claros consiste en observar cómo reaccionan los distintos sectores políticos cuando pierden el poder o cuando el resultado de una elección les resulta adverso. En diversos países de América Latina —como Chile, Bolivia, Honduras y Ecuador— se advierte un fenómeno que se repite con frecuencia: cuando un gobierno de izquierda es reemplazado por uno de derecha, la respuesta no es la aceptación institucional, sino la agitación, los disturbios y las acciones destinadas a alterar el orden público. En contraste, cuando los resultados electorales favorecen a la izquierda, la normalidad prevalece. La derecha, en su gran mayoría, asume los resultados y respeta el orden sin recurrir a la violencia como instrumento de presión política; los pocos desmanes aislados provienen de individuos torpes o de provocadores infiltrados para generar desestabilización.
|
|
||||||
|
|
||||||
Esta profunda diferencia y asimetría moral se manifiesta con total claridad en la seguridad de los líderes durante las contiendas políticas.
|
|
||||||
|
|
||||||
Recuerdo perfectamente las duras críticas hacia el presidente de Colombia por asistir a sus mítines rodeado de estrictas medidas de protección y blindajes, utilizándolo para presentarlo como alguien temeroso. Sin embargo, ese dirigente debía proteger su vida porque existían amenazas concretas de muerte en su contra. Por el contrario, el candidato de izquierda caminaba libremente y sin temores. La explicación es de pura lógica: sus seguidores jamás atentarían contra su propio líder, y los sectores de derecha no somos asesinos ni utilizamos la eliminación física del adversario como herramienta de acción política. Es en esa necesidad de protección donde se evidencia de qué lado se encuentra la inclinación hacia el daño y el mal.
|
|
||||||
|
|
||||||
No se trata de generalizar de forma absoluta; reconozco que no todos quienes se identifican con la izquierda participan de esas conductas. Muchos ciudadanos apoyan estos movimientos de buena fe, convencidos de que representan un camino hacia una sociedad más justa. Sin embargo, marchan engañados por planteamientos ideológicos que prometen justicia social, pero cuyas consecuencias reales ignoran por completo.
|
|
||||||
|
|
||||||
Los espejos de la región son dolorosos, evidentes y no admiten discusión.
|
|
||||||
|
|
||||||
Cuba, que en su momento fue una de las islas más prósperas y adelantadas del continente, hoy se hunde en un profundo deterioro económico y social, careciendo incluso de servicios básicos, como el suministro de energía eléctrica.
|
|
||||||
El mismo libreto de destrucción institucional y económica lo han seguido Nicaragua y Venezuela.
|
|
||||||
|
|
||||||
Esta última nación se encuentra hoy en una transición crucial; y mi deseo ferviente es que este proceso culmine plenamente para que el pueblo venezolano rompa sus cadenas, recupere sus instituciones democráticas y vuelva a vivir en absoluta y total libertad.
|
|
||||||
|
|
||||||
La historia reciente ofrece ejemplos suficientes para evaluar cada modelo; por ello, reafirmo mi convicción de que la defensa de la libertad, el Estado de Derecho y la convivencia pacífica son los pilares indispensables para construir sociedades verdaderamente prósperas.
|
|
||||||
|
|
||||||
**Dr. José Benjamín Pérez Matos**<br>
|
|
||||||
Presidente<br>
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
---
|
|
||||||
locale: es
|
|
||||||
title: '¿Paz temporal o el inicio de un reordenamiento global en Oriente Medio?'
|
|
||||||
date: 2026-07-26
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-07-26-paz-temporal-o-el-inicio-de-un-reordenamiento-global-en-oriente-medio
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# ¿Paz temporal o el inicio de un reordenamiento global en Oriente Medio?
|
|
||||||
|
|
||||||
Los acontecimientos de las últimas semanas en Oriente Medio han vuelto a colocar a la región en el centro de la atención internacional. La reciente pausa en los bombardeos estadounidenses sobre territorio iraní, tras casi dos semanas de hostilidades continuas, ha abierto un compás de espera que numerosos analistas presentan como un posible avance hacia una instancia de diplomacia estratégica.
|
|
||||||
|
|
||||||
Las conversaciones técnicas desarrolladas en Omán, y los esfuerzos orientados a estabilizar el tránsito por el estrecho de Ormuz, parecen reflejar la intención de reducir la tensión y evitar una escalada que comprometa aún más la estabilidad regional y el comercio internacional.
|
|
||||||
|
|
||||||
Sin embargo, para el **Dr. José Benjamín Pérez Matos**, detrás de esos movimientos diplomáticos existe una realidad mucho más profunda y trascendente que no puede ser comprendida únicamente desde la perspectiva de la política internacional.
|
|
||||||
|
|
||||||
Al referirse al momento que atraviesa la región, expresó:
|
|
||||||
|
|
||||||
**«Ahora, en estos días tiene Estados Unidos esa guerra ahí con Irán todavía; y lo último que escuché: que parece que hasta ahí van a dejarlo, ¡cuando deben exterminar por completo, de raíz, el problema! Si siguen tirando dos bombitas y se retiran, van ellos, más adelante, a hacer lo mismo. ¿Ven? Son procesos aparentemente de paz temporal, pero sigue el mal allí»**.
|
|
||||||
|
|
||||||
Estas palabras invitan a distinguir entre una paz circunstancial y la eliminación definitiva de las causas que originan el conflicto. Desde esta perspectiva, una interrupción temporal de las operaciones militares no constituye necesariamente la resolución del problema, sino apenas una pausa dentro de un proceso que todavía permanece abierto.
|
|
||||||
|
|
||||||
La propia evolución de los acontecimientos internacionales confirma la fragilidad del escenario actual.
|
|
||||||
|
|
||||||
Mientras el ejército de los Estados Unidos suspendió sus ataques aéreos tras trece noches consecutivas de bombardeos, la incertidumbre continúa predominando en la comunidad internacional. El panorama permanece abierto, y las principales potencias siguen evaluando los próximos pasos, en una región cuya estabilidad continúa siendo determinante para el equilibrio geopolítico mundial.
|
|
||||||
|
|
||||||
En este contexto, el presidente de los Estados Unidos, Donald Trump, ha mantenido una postura que combina la presión diplomática con la posibilidad de alcanzar un entendimiento con Teherán.
|
|
||||||
|
|
||||||
Por un lado, ha formulado severas advertencias al régimen iraní; por el otro, ha alimentado públicamente las expectativas de una negociación; al afirmar, ante los medios reunidos en la Oficina Oval:
|
|
||||||
|
|
||||||
«Podemos negociar con ellos, que es lo que también estamos haciendo ahora mismo».
|
|
||||||
|
|
||||||
Sin embargo, el propio mandatario también moderó esas expectativas al declarar que no considera que Irán esté “ready (o listo) todavía” para alcanzar un acuerdo definitivo.
|
|
||||||
|
|
||||||
Al mismo tiempo, reconoció que:
|
|
||||||
|
|
||||||
«Creo que se están poniendo cada vez más serios a medida que pasan los días; quizá por la razón obvia».
|
|
||||||
|
|
||||||
Las declaraciones del presidente estadounidense reflejan un escenario en el que continúan coexistiendo la presión militar, la negociación diplomática y la incertidumbre sobre el desenlace definitivo del conflicto.
|
|
||||||
|
|
||||||
## El trasfondo profético de la crisis
|
|
||||||
|
|
||||||
Para el **Dr. José Benjamín Pérez Matos**, comprender plenamente lo que ocurre entre Washington y Teherán exige levantar la mirada por encima de la simple crónica periodística y analizar los acontecimientos desde una perspectiva más amplia.
|
|
||||||
|
|
||||||
En ese sentido sostuvo que resulta necesario observar el mapa geopolítico a través del lente de las profecías bíblicas contenidas en el capítulo 2 del libro de Daniel.
|
|
||||||
En ese contexto afirmó:
|
|
||||||
|
|
||||||
**«Ese reino de Persia, ese reino de Irán, tiene que ser quitado completamente, para que solamente quede el reino de Roma; o sea, el reino de los pies de hierro y barro cocido»**.
|
|
||||||
|
|
||||||
Bajo esta perspectiva teológica, el orden mundial final no contempla la coexistencia de distintos bloques geopolíticos desarrollándose simultáneamente como estructuras paralelas de poder.
|
|
||||||
|
|
||||||
Como explicó el **Dr. José Benjamín Pérez Matos**:
|
|
||||||
|
|
||||||
**«No puede haber un reino también, corriendo paralelo a ese reino último de las piernas de hierro y barro cocido; solamente tiene que quedar ese. Por lo tanto, esos residuos que están quedando de ese imperio de Persia: Irán, tiene que ser quitado. Y eso es una señal muy grande, cuando eso suceda. Lo cual marcará un hito profético definitivo en estos días»**.
|
|
||||||
|
|
||||||
Desde esta interpretación, los acontecimientos actuales trascienden el ámbito estrictamente político y militar, para insertarse dentro de un proceso histórico de mayor alcance, cuyo desarrollo, según el **Dr. José Benjamín Pérez Matos**, forma parte del cumplimiento progresivo de las profecías bíblicas.
|
|
||||||
|
|
||||||
## Diplomacia de alta presión en la Casa Blanca
|
|
||||||
|
|
||||||
Es precisamente en este escenario de máxima tensión donde adquiere una relevancia particular la visita del primer ministro del Estado de Israel, Benjamín Netanyahu, a los Estados Unidos.
|
|
||||||
|
|
||||||
Aunque el motivo oficial del viaje es participar de las honras fúnebres del fallecido senador Lindsey Graham —descrito por la Oficina del Primer Ministro como “un amigo de Israel”—, las reuniones previstas entre las máximas autoridades de ambos países tendrán como eje el futuro inmediato de Oriente Medio y los desafíos estratégicos que enfrenta la región.
|
|
||||||
|
|
||||||
Al referirse a esos encuentros, el **Dr. José Benjamín Pérez Matos** manifestó:
|
|
||||||
|
|
||||||
**«Ahora, esperemos que… tienen una reunión en estos días en Washington, o en Nueva York. El primer ministro de Israel, Benjamín Netanyahu, va a estar allá; y van a hablar sobre todo eso también»**.
|
|
||||||
|
|
||||||
La importancia de estas conversaciones radica en que Israel ha observado con cautela el desarrollo de los ataques estadounidenses, plenamente consciente de que en esta crisis se encuentra comprometido el control de una vía marítima estratégica por la que circula aproximadamente el veinte por ciento del petróleo que se comercializa en el mundo.
|
|
||||||
|
|
||||||
En consecuencia, la reactivación de los contactos bilaterales entre Washington y Jerusalén busca unificar criterios frente a un enemigo común y coordinar los próximos pasos estratégicos en un escenario marcado por la permanente volatilidad del golfo Pérsico.
|
|
||||||
|
|
||||||
## La carrera contra el reloj electoral
|
|
||||||
|
|
||||||
Además del componente militar y diplomático, el factor tiempo aparece como uno de los elementos más sensibles de la coyuntura actual.
|
|
||||||
|
|
||||||
La proximidad de los próximos procesos electorales introduce una variable política que puede modificar significativamente el escenario geopolítico.
|
|
||||||
|
|
||||||
En el plano interno de los Estados Unidos, el presidente Donald Trump ha restado importancia a las especulaciones sobre el eventual impacto electoral del aumento de los precios de los combustibles.
|
|
||||||
|
|
||||||
Ante la prensa afirmó:
|
|
||||||
|
|
||||||
«A pesar de lo que todo el mundo dice sobre las elecciones, no tengo prisa... Las elecciones se resuelven solas».
|
|
||||||
|
|
||||||
Sin embargo, el **Dr. José Benjamín Pérez Matos** llamó la atención sobre otro proceso electoral que, desde su perspectiva, reviste una importancia todavía mayor para el futuro inmediato de Oriente Medio: las elecciones previstas en Israel.
|
|
||||||
|
|
||||||
Sobre este punto expresó:
|
|
||||||
|
|
||||||
**«Pero miren lo que pasa en Israel: ahora van a haber elecciones, en octubre. Tienen que apurarse. Porque si les cae allí un primer ministro que no esté en favor (y en esa línea de pensamiento) del mundo religioso, de los ortodoxos, y cae otro y gana las elecciones en octubre, se le van a poner las cosas difíciles a Israel. O sea, más bien debe de aprovechar este término que queda, por si acaso pasa una sorpresa ahí en octubre»**.
|
|
||||||
|
|
||||||
Estas palabras reflejan la importancia que el **Dr. José Benjamín Pérez Matos** atribuye al calendario político israelí dentro del contexto regional. Desde esta perspectiva, el tiempo disponible para consolidar determinadas decisiones estratégicas resulta limitado y podría verse condicionado por el resultado de los próximos comicios.
|
|
||||||
|
|
||||||
Como señaló el propio **Dr. José Benjamín Pérez Matos**:
|
|
||||||
|
|
||||||
**«el margen de maniobra para consolidar las posiciones de fuerza es sumamente estrecho. Los actores políticos deben actuar con presteza ante la posibilidad de un vuelco electoral o una sorpresa en las urnas»**.
|
|
||||||
|
|
||||||
Esta advertencia constituye el cierre natural del análisis geopolítico desarrollado a lo largo de esta reflexión. Sin embargo, para el **Dr. José Benjamín Pérez Matos**, los acontecimientos internacionales no pueden comprenderse únicamente desde la perspectiva de las decisiones humanas, de la diplomacia o de la estrategia militar.
|
|
||||||
|
|
||||||
Por encima de todos esos factores existe un propósito superior cuyo cumplimiento, afirma, continúa desarrollándose conforme al programa profético revelado en las Escrituras.
|
|
||||||
|
|
||||||
Por ello concluyó su exposición recordando:
|
|
||||||
|
|
||||||
**«Pero recuerden que todo es, y todo se cumplirá, conforme a las profecías. Nada de esto queda en manos humanas»**.
|
|
||||||
|
|
||||||
Desde la perspectiva presentada por el **Dr. José Benjamín Pérez Matos**, los acontecimientos que hoy se desarrollan en Oriente Medio trascienden la coyuntura internacional y constituyen parte de un proceso histórico de mayor alcance. Más allá de las negociaciones diplomáticas, de las decisiones militares o de los cambios políticos que puedan producirse en los distintos países involucrados, el desenlace definitivo responderá al cumplimiento del propósito profético que, según las Escrituras, habrá de conducir al establecimiento del orden final anunciado en el libro de Daniel.
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
---
|
|
||||||
locale: es
|
|
||||||
title: 'Un mundo en transición: guerras, estremecimientos y el cambio de reino'
|
|
||||||
date: 2026-08-16
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-08-16-un-mundo-en-transicion-guerras-estremecimientos-y-el-cambio-de-reino
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# Un mundo en transición: guerras, estremecimientos y el cambio de reino
|
|
||||||
|
|
||||||
### Las guerras que continúan abiertas, la situación de Irán y los grandes fenómenos naturales que estremecen distintas regiones del planeta, forman parte, desde la perspectiva profética expuesta por el Dr. José Benjamín Pérez Matos, de un escenario de transición que la humanidad debe observar con atención. En medio de ese proceso, Israel y Jerusalén ocupan un lugar central en el cumplimiento de las profecías y en la futura instauración del Reino del Mesías.
|
|
||||||
|
|
||||||
El mundo atraviesa una etapa marcada simultáneamente por conflictos geopolíticos, guerras y fenómenos naturales de una magnitud que obliga a mirar con atención lo que está sucediendo.
|
|
||||||
|
|
||||||
La guerra entre Rusia y Ucrania continúa; persisten las tensiones y el conflicto en torno a Irán; y, paralelamente, terremotos, huracanes, ciclones, tormentas, tsunamis, maremotos y erupciones volcánicas, parecen recordarnos constantemente la fragilidad del orden humano.
|
|
||||||
|
|
||||||
El **Dr. José Benjamín Pérez Matos** ha llamado a observar estos acontecimientos desde una perspectiva profética, entendiendo que no se trata simplemente de hechos aislados, sino de manifestaciones que acompañan un proceso mucho mayor: el cambio de los reinos gentiles al Reino del Mesías.
|
|
||||||
|
|
||||||
En relación con la situación de Irán, su planteamiento ha sido categórico:
|
|
||||||
|
|
||||||
**«Miren las situaciones del mundo, las guerras que hay: Todavía Rusia está en guerra con Ucrania. Ves la guerra que hay con Irán; la cual deben de terminar ya, de una vez y por todas, ese reino, para que puedan entrar esas otras fases y etapas físicas como nación, pueda entrar el próximo paso».**
|
|
||||||
|
|
||||||
Según esta interpretación, existe una secuencia profética que debe cumplirse. Por ello, el **Dr. Pérez Matos** sostiene:
|
|
||||||
|
|
||||||
**«No se puede pasar a los próximos pasos si no se termina ese paso de eliminar ese reino (que todavía está dando pataletas allí), para que quede solamente el reino de los pies de hierro y barro cocido. Ya eso lo hemos venido hablando».**
|
|
||||||
|
|
||||||
Esta referencia remite directamente a la imagen profética presentada en el capítulo 2 del libro de Daniel y a la sucesión de reinos representada en ella. Desde esa perspectiva, los acontecimientos contemporáneos no pueden ser considerados únicamente desde los cálculos políticos, diplomáticos o militares del presente: forman parte de un proceso profético cuyo desarrollo conduce finalmente al establecimiento del Reino del Mesías.
|
|
||||||
|
|
||||||
## El llamado a Israel y a sus dirigentes
|
|
||||||
|
|
||||||
Dentro de este escenario, Israel ocupa un lugar determinante. El **Dr. José Benjamín Pérez Matos** dirigió particularmente sus palabras al primer ministro israelí, Benjamín Netanyahu:
|
|
||||||
|
|
||||||
**«Y los líderes…, tanto el de Israel: Benjamín Netanyahu, primer ministro de Israel, debe de tomar en serio estas palabras, y que termine por completo de sacar ese reino de Persia, para que así puedan entrar esas fases y esas etapas para esta introducción del establecimiento del Reino del Mesías».**
|
|
||||||
|
|
||||||
Las decisiones políticas pueden estar acompañadas por alianzas, asesoramiento internacional y cálculos estratégicos. Sin embargo, desde la perspectiva planteada por el **Dr. Pérez Matos**, existe un criterio superior que debe orientar esas decisiones:
|
|
||||||
|
|
||||||
**«Y puede haber naciones que le den apoyo y que estén dándole consejos, pero el consejo mejor que pueden ellos recibir es el Consejo de Dios. Y tienen que recibirlo bajo las profecías que fueron habladas. Y tiene que estar basado, todo lo que hagan, en las profecías; no en lo que digan los demás. ¡Y todo le irá bien! Porque todo es un Programa que se está desarrollando, el cual es ese cambio de reino; e Israel tiene una parte muy importante».**
|
|
||||||
|
|
||||||
Esa importancia de Israel no se limita a su protagonismo actual en Medio Oriente. Dentro de la visión profética expuesta, su territorio posee una función futura fundamental, con Jerusalén como centro de gobierno:
|
|
||||||
|
|
||||||
**«La parte de Israel es, vean, el territorio; y desde allí es que se estará gobernando todo el planeta Tierra completo y el universo completo. Galaxias, todos los planetas…, todo va a ser gobernado, miren, desde ese puntito allí, en donde será la capital del planeta Tierra completo; y de las galaxias y de todo el sistema sería la Tierra; pero en la Tierra estaría la capital, que es Jerusalén».**
|
|
||||||
|
|
||||||
Por eso, hablar de Israel y Jerusalén desde esta perspectiva, implica hablar no solamente de la geopolítica contemporánea, sino también del futuro orden anunciado en las profecías.
|
|
||||||
|
|
||||||
## El cambio de reino y los estremecimientos de la Tierra
|
|
||||||
|
|
||||||
Los grandes cambios históricos nunca han estado exentos de conmociones. Guerras, conflictos y transformaciones profundas acompañaron anteriores cambios de reinos. La pregunta, entonces, es qué ocurrirá en el tránsito definitivo desde los reinos gentiles hacia el Reino del Mesías.
|
|
||||||
|
|
||||||
El **Dr. José Benjamín Pérez Matos** lo expresa de esta manera:
|
|
||||||
|
|
||||||
**«Ahora, para esos cambios de reino, vean, hubo situaciones, guerras y todo eso. Y dijimos: ¿Cómo será para este cambio de reino ahora, de los gentiles al Reino del Mesías? Pues miren, ahí va a estar todo siendo cumplido. Lo que fue en parte en esos cambios de reino, ahora estaremos viéndolo en todas esas manifestaciones. Tanto la Tierra gimiendo…».**
|
|
||||||
|
|
||||||
Esta imagen de una creación que gime encuentra su referencia en Romanos, capítulo 8:
|
|
||||||
|
|
||||||
**«Romanos, capítulo 8, nos habla de eso también: “Esperando la manifestación de los hijos de Dios”».**
|
|
||||||
|
|
||||||
Desde esta lectura, los acontecimientos de la naturaleza adquieren también una dimensión profética. No deben ser observados únicamente como sucesos físicos separados unos de otros, sino como parte de un escenario que llama a la humanidad —y especialmente al pueblo de Dios— a estar atento.
|
|
||||||
|
|
||||||
**«Y vemos volcanes, vemos terremotos, maremotos, vemos tsunamis, tormentas, huracanes, ciclones y todas esas cosas, que van siendo manifestados en este tiempo cada vez peores. Huracanes que nunca se han visto, de una fuerza sobrenatural…, que nunca jamás ha pasado un huracán así, y ahora lo estamos viendo».**
|
|
||||||
|
|
||||||
## Venezuela, Colombia y un mundo que no está preparado
|
|
||||||
|
|
||||||
Los recientes terremotos ocurridos en Venezuela y Colombia fueron señalados por el **Dr. José Benjamín Pérez Matos** como ejemplos concretos de esos estremecimientos:
|
|
||||||
|
|
||||||
**«Terremotos…, miren el de Venezuela, lo que ocurrió allí. Ahora con el que ocurrió en Colombia, en donde no se esperaban eso. Y no tiene que ver con el de Venezuela, fueron dos fallas distintas, totalmente distintas».**
|
|
||||||
|
|
||||||
Sobre el terremoto de Colombia, agregó:
|
|
||||||
|
|
||||||
**«Y una…, algo curioso: dicen que eso fue de arriba a abajo; cubrió toda esa parte izquierda (mirando el mapa de frente), de arriba hacia abajo: desde Medellín, bajó por ahí, todo, Cali, hasta abajo. Y vemos cómo el mundo, pues… como que no está preparado para eso».**
|
|
||||||
|
|
||||||
Más allá de la dimensión profética con la cual se interpreten estos acontecimientos, existe una dimensión profundamente humana que nunca debe quedar relegada. Los terremotos destruyen viviendas, alteran comunidades y, sobre todo, cobran vidas.
|
|
||||||
|
|
||||||
**«Y en esos terremotos, pues hay muchas pérdidas también, humanas. Ya van… unos ciento y pico vi anoche, por ahí».**
|
|
||||||
|
|
||||||
Ante ese sufrimiento, las palabras deben convertirse también en solidaridad. El **Dr. José Benjamín Pérez Matos** expresó su acompañamiento al pueblo colombiano y, especialmente, a las familias que han perdido seres queridos:
|
|
||||||
|
|
||||||
**«Y nos unimos al pueblo colombiano. Y deseamos que Dios conforte los corazones de aquellos que han perdido sus seres queridos; y que Dios les dé la fortaleza; y que escuchen esa Voz del Ángel Fuerte, la Voz del Ángel con el Evangelio Eterno, diciendo: “Temed a Dios, y dadle gloria, porque la hora de Su juicio ha llegado”. Apocalipsis, capítulo 14».**
|
|
||||||
|
|
||||||
## Un llamado a prepararse
|
|
||||||
|
|
||||||
La lectura profética de estos acontecimientos no conduce únicamente a interpretar lo que sucede. Implica también preparación.
|
|
||||||
|
|
||||||
El **Dr. José Benjamín Pérez Matos** advierte:
|
|
||||||
|
|
||||||
**«Porque la ira de Dios estará siendo manifestada en este planeta Tierra ya durante la gran tribulación, pero antes hay unos estremecimientos, en donde el pueblo de Dios tiene que estar listo para recibir las bendiciones».**
|
|
||||||
|
|
||||||
En ese marco aparece también la Fiesta de las Trompetas y el entrelace profético con aquello que habrá de manifestarse durante el Reino Milenial:
|
|
||||||
|
|
||||||
**«Todo se va a pintar en ese entrelace de la Fiesta de las Trompetas. Se va a estar viendo un entrelace de cómo será el Reino Milenial, donde lo que se van a ver, en su mayoría o totalmente, son carpas».**
|
|
||||||
|
|
||||||
La referencia a las carpas posee, además, una dimensión práctica frente a los grandes movimientos de la tierra:
|
|
||||||
|
|
||||||
**«Porque no se va a meter usted debajo de un edificio que esté todo agrietado. Y lo más cómodo es una carpa: caseta de campaña, una carpa, cosas prácticas; que si hay un movimiento, pues eso no se le cae encima».**
|
|
||||||
|
|
||||||
La conclusión, por tanto, no es solamente contemplativa. Los acontecimientos atmosféricos y naturales constituyen, dentro de esta perspectiva, un aviso:
|
|
||||||
|
|
||||||
**«O sea que Dios nos está dando un aviso con todos esos eventos atmosféricos y de la naturaleza que están ocurriendo, para que el pueblo de Dios se prepare».**
|
|
||||||
|
|
||||||
Vivimos en un mundo sometido a profundas tensiones: guerras que no terminan, estructuras de poder que se enfrentan, sociedades expuestas a fenómenos naturales devastadores, y una humanidad que —muchas veces— descubre que sus sistemas y ciudades no están preparados para responder a acontecimientos de gran magnitud.
|
|
||||||
|
|
||||||
Pero, desde la perspectiva profética, estos estremecimientos no anuncian solamente destrucción; también señalan transición. Los reinos humanos son temporales; el Programa de Dios continúa desarrollándose; Israel conserva su lugar dentro de ese Programa; Jerusalén tiene reservado un papel central; y el pueblo de Dios está llamado a comprender el tiempo, escuchar el aviso y prepararse.
|
|
||||||
|
|
||||||
Porque, como concluye el **Dr. José Benjamín Pérez Matos**:
|
|
||||||
|
|
||||||
**«Y cuando se habla de terremotos, se habla de liberación».**
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
locale: fr
|
|
||||||
title: 'La véritable nature des idées'
|
|
||||||
date: 2026-06-29
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-06-29-la-veritable-nature-des-idees
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# La véritable nature des idées
|
|
||||||
|
|
||||||
Les campagnes électorales sont souvent chargées de promesses, de slogans et de discours soigneusement élaborés pour conquérir le vote des citoyens. Cependant, une fois la lutte politique terminée, vient le moment où les idées quittent le plan théorique et commencent à se manifester dans la réalité. Je soutiens fermement que c'est précisément à ce moment-là qu'il devient possible de connaître la véritable nature d'une idéologie : non pas par ce qu'elle promet, mais par la conduite qu'elle inspire chez ses dirigeants, ses militants et ceux qui agissent en son nom.
|
|
||||||
|
|
||||||
Les idéologies ne doivent pas être jugées par la beauté de leurs discours, mais par leurs résultats concrets.
|
|
||||||
|
|
||||||
Dans cette perspective, l'un des indicateurs les plus clairs consiste à observer comment réagissent les différents secteurs politiques lorsqu'ils perdent le pouvoir ou lorsque le résultat d'une élection leur est défavorable. Dans divers pays d'Amérique latine —comme le Chili, la Bolivie, le Honduras et l'Équateur— on observe un phénomène qui se répète fréquemment : lorsqu’un gouvernement de gauche est remplacé par un gouvernement de droite, la réponse n'est pas l'acceptation institutionnelle, mais l'agitation, les troubles et les actions destinées à altérer l'ordre public. En revanche, lorsque les résultats électoraux favorisent la gauche, la normalité prévaut. La droite, dans sa grande majorité, accepte les résultats et respecte l'ordre sans recourir à la violence comme instrument de pression politique ; les rares débordements isolés proviennent d'individus malavisés ou de provocateurs infiltrés pour générer de la déstabilisation.
|
|
||||||
|
|
||||||
Cette profonde différence et asymétrie morale se manifeste avec une clarté totale dans la sécurité des dirigeants pendant les campagnes politiques.
|
|
||||||
Je me souviens parfaitement des vives critiques envers le président de la Colombie pour avoir assisté à ses réunions publiques entouré d’un important dispositif de sécurité, l'utilisant pour le présenter comme quelqu'un de craintif. Cependant, ce dirigeant devait protéger sa vie car il existait des menaces concrètes de mort à son encontre. Au contraire, le candidat de gauche marchait librement et sans crainte. L'explication est purement logique : ses partisans n'attaqueraient jamais leur propre leader, et nous, dans les secteurs de droite, ne sommes pas des assassins et n'avons pas recours à l'élimination physique de l'adversaire comme outil d'action politique. C'est dans ce besoin de protection que se révèle de quel côté se trouve l'inclination vers le mal et la violence.
|
|
||||||
|
|
||||||
Il ne s'agit pas de généraliser de manière absolue ; je reconnais que tous ceux qui s'identifient à la gauche ne participent pas à ces comportements. Beaucoup de citoyens soutiennent ces mouvements de bonne foi, convaincus qu'ils représentent un chemin vers une société plus juste. Cependant, ils sont guides par des idées trompeuses qui promettent la justice sociale, mais dont ils ignorent complètement les conséquences réelles.
|
|
||||||
|
|
||||||
Les exemples de la région son éloquents, douloureux et ne souffrent aucune discussion.
|
|
||||||
|
|
||||||
Cuba, qui à l'époque était l'une des îles les plus prospères et avancées du continent, sombre aujourd'hui dans un profond déclin économique et social, manquant même de services de base, comme l'approvisionnement en électricité. Le même scénario de destruction institutionnelle et économique a été suivi par le Nicaragua et le Venezuela.
|
|
||||||
|
|
||||||
Cette dernière nation se trouve aujourd'hui dans une transition cruciale ; et mon ardent désir est que ce processus aboutisse pleinement afin que le peuple vénézuélien rompe ses chaînes, récupère ses institutions démocratiques et vive à nouveau en liberté totale.
|
|
||||||
|
|
||||||
L'histoire récente offre des exemples suffisants pour évaluer chaque modèle ; c'est pourquoi je réaffirme ma conviction que la défense de la liberté, l'État de droit et la coexistence pacifique sont les piliers indispensables pour construire des sociétés véritablement prospères.
|
|
||||||
|
|
||||||
|
|
||||||
**Dr. José Benjamín Pérez Matos**<br>
|
|
||||||
Président<br>
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
---
|
|
||||||
locale: fr
|
|
||||||
title: Paix temporaire ou le début d'un réaménagement global au Moyen-Orient ?
|
|
||||||
date: 2026-07-26
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-07-26-paix-temporaire-ou-le-debut-dun-reamenagement-global-au-moyen-orient
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# Paix temporaire ou le début d'un réaménagement global au Moyen-Orient ?
|
|
||||||
|
|
||||||
Les événements des dernières semaines au Moyen-Orient ont remis la région au centre de l'attention internationale. La récente pause dans les bombardements américains sur le territoire iranien, après près de deux semaines d'hostilités continues, a ouvert une période d'attente que de nombreux analystes présentent comme une possible avancée diplomatique.
|
|
||||||
|
|
||||||
Les conversations techniques menées à Oman, et les efforts visant à stabiliser le transit par le détroit d'Ormuz, semblent refléter l'intention de réduire les tensions régionales et d'éviter une escalade qui compromettrait encore plus la stabilité régionale et le commerce international.
|
|
||||||
|
|
||||||
Cependant, pour le **Dr. José Benjamín Pérez Matos**, derrière ces mouvements diplomatiques se cache une réalité bien plus profonde et transcendante qui ne peut être comprise uniquement depuis la perspective de la politique internationale.
|
|
||||||
|
|
||||||
En se référant au moment que traverse la région, il a exprimé :
|
|
||||||
|
|
||||||
**«Maintenant, ces jours-ci, les États-Unis ont encore cette guerre avec l'Iran ; et la dernière chose que j'ai entendue : il semble qu'ils vont s'arrêter là, alors qu'ils devraient éradiquer le problème à la racine, le problème ! S'ils continuent à lancer deux bombes et à se retirer, eux, plus tard, ils vont faire la même chose. Vous voyez ? Ce sont des processus apparemment de paix temporaire, mais le mal démure ».**
|
|
||||||
|
|
||||||
Ces mots invitent à distinguer entre une paix circonstancielle et l'élimination définitive les causes à l'origine du conflit. Dans cette perspective, une interruption temporaire des opérations militaires ne constitue pas nécessairement la résolution du problème, mais seulement une pause dans un processus qui reste ouvert.
|
|
||||||
|
|
||||||
L'évolution même des événements internationaux confirme la fragilité du scénario actuel.
|
|
||||||
|
|
||||||
Alors que l’armée américaine a suspendu ses frappes aériennes après treize nuits consécutives de bombardements, l'incertitude continue de prédominer dans la communauté internationale. Le panorama reste ouvert, et les principales puissances continuent d'évaluer les prochaines étapes, dans une région dont la stabilité demeure déterminante pour l'équilibre géopolitique mondial.
|
|
||||||
|
|
||||||
Dans ce contexte, le président des États-Unis, Donald Trump, a maintenu une position qui combine la pression diplomatique avec la possibilité d'atteindre un accord avec Téhéran.
|
|
||||||
|
|
||||||
D'une part, il a formulé de sévères avertissements au régime iranien ; d'autre part, il a alimenté publiquement les attentes d'une négociation ; en affirmant, devant les médias réunis dans le Bureau ovale :
|
|
||||||
|
|
||||||
«Nous pouvons négocier avec eux, ce que nous faisons en ce moment même.»
|
|
||||||
|
|
||||||
Cependant, le président lui-même a également tempéré ces attentes en déclarant qu'il ne considère pas que l'Iran soit « prêt » (ready) pour parvenir à un accord définitif.
|
|
||||||
|
|
||||||
En même temps, il a reconnu que :
|
|
||||||
|
|
||||||
«Je pense qu'ils deviennent de plus en plus sérieux au fil des jours; peut-être pour la raison évidente.»
|
|
||||||
|
|
||||||
Les déclarations du président américain reflètent un scénario dans lequel continuent de coexister la pression militaire, la négociation diplomatique et l'incertitude quant à l'issue définitive du conflit.
|
|
||||||
|
|
||||||
## Le contexte prophétique de la crise
|
|
||||||
|
|
||||||
Pour le **Dr. José Benjamín Pérez Matos**, comprendre pleinement ce qui se passe entre Washington et Téhéran exige d'aller au-delà de la simple chronique journalistique et d'analyser les événements d'une perspective plus large.
|
|
||||||
|
|
||||||
En ce sens, il a soutenu qu'il est nécessaire d'observer la carte géopolitique à travers le prisme des prophéties bibliques contenues dans le chapitre 2 du livre de Daniel. Dans ce contexte, il a affirmé :
|
|
||||||
|
|
||||||
**«Ce royaume de Perse, ce royaume d'Iran, doit être complètement supprimé, afin qu'il ne reste que le royaume de Rome ; c'est-à-dire, le royaume des pieds de fer et d'argile cuite».**
|
|
||||||
|
|
||||||
Dans cette perspective théologique, l'ordre mondial final ne prévoit pas la coexistence de différents blocs géopolitiques se développant simultanément comme des structures parallèles de pouvoir.
|
|
||||||
|
|
||||||
Comme l'a expliqué le **Dr. José Benjamín Pérez Matos** :
|
|
||||||
|
|
||||||
**«Il ne peut pas y avoir un royaume parallèle à ce dernier royaume des jambes de fer et d'argile cuite ; il ne doit rester que celui-là. Par conséquent, ces résidus qui restent de cet empire de Perse : L'Iran doit être éliminé. Et c'est un très grand signe, quand cela arrivera. Ce qui marquera un jalon prophétique définitif en ces jours».**
|
|
||||||
|
|
||||||
Selon cette interprétation, les événements actuels transcendent le domaine strictement politique et militaire, pour s'inscrire dans un processus historique de plus grande envergure, dont le développement, selon le **Dr. José Benjamín Pérez Matos**, fait partie de l'accomplissement progressif des prophéties bibliques.
|
|
||||||
|
|
||||||
## Diplomatie de haute pression à la Maison Blanche
|
|
||||||
|
|
||||||
C'est précisément dans ce contexte de tension maximale que la visite du Premier ministre de l'État d'Israël, Benjamin Netanyahu, aux États-Unis revêt une importance particulière.
|
|
||||||
|
|
||||||
Bien que le motif officiel du voyage soit de participer aux funérailles du sénateur décédé Lindsey Graham —décrit par le Bureau du Premier ministre comme « un ami d'Israël »—, les réunions prévues entre les plus hautes autorités des deux pays auront pour principal sujet l'avenir immédiat du Moyen-Orient et les défis stratégiques auxquels la région est confrontée.
|
|
||||||
|
|
||||||
En se référant à ces rencontres, le **Dr. José Benjamín Pérez Matos** a déclaré :
|
|
||||||
|
|
||||||
**«Maintenant, espérons que… ils ont une réunion ces jours-ci à Washington, ou à New York. Le Premier ministre israélien, Benyamin Netanyahou, va être là-bas ; et ils vont parler de tout cela aussi».**
|
|
||||||
|
|
||||||
L'importance de ces conversations réside dans le fait qu'Israël a observé avec prudence le développement des attaques américaines, pleinement conscient que dans cette crise est engagé le contrôle d'une voie maritime stratégique par laquelle circule environ vingt pour cent du pétrole commercialisé dans le monde.
|
|
||||||
|
|
||||||
En conséquence, la réactivation des contacts bilatéraux entre Washington et Jérusalem vise à harmoniser les positions face à un ennemi commun et à coordonner les prochaines étapes stratégiques dans un scénario marqué par la volatilité permanente du golfe Persique.
|
|
||||||
|
|
||||||
## La course contre la montre électorale
|
|
||||||
|
|
||||||
En plus du composant militaire et diplomatique, le facteur temps apparaît comme l'un des éléments les plus sensibles de la conjoncture actuelle.
|
|
||||||
|
|
||||||
La proximité des prochaines élections introduit une variable politique qui peut modifier significativement le paysage géopolitique.
|
|
||||||
|
|
||||||
Sur le plan interne des États-Unis, le président Donald Trump a minimisé les spéculations sur l'éventuel impact électoral de l'augmentation des prix des combustibles.
|
|
||||||
|
|
||||||
Devant la presse, il a affirmé :
|
|
||||||
|
|
||||||
«Malgré ce que tout le monde dit sur les élections, je ne suis pas pressé… Les élections se résolvent d'elles-mêmes.
|
|
||||||
|
|
||||||
Cependant, le **Dr. José Benjamín Pérez Matos** a attiré l'attention sur un autre processus électoral qui, de son point de vue, revêt une importance encore plus grande pour l'avenir immédiat du Moyen-Orient : les élections prévues en Israël.
|
|
||||||
|
|
||||||
À ce sujet, il a exprimé :
|
|
||||||
|
|
||||||
**«Mais regardez ce qui se passe en Israël : il va y avoir des élections, en octobre. Ils doivent se dépêcher. Parce que si un premier ministre qui ne soit pas favorable (et dans cette ligne de pensée) au monde religieux, des orthodoxes, arrive là-bas, et qu'un autre arrive au pouvoir et gagne les élections en octobre, les choses vont devenir difficiles pour Israël. C'est-à-dire, il doit plutôt profiter du temps restant, au cas où une surprise se produirait en octobre».**
|
|
||||||
|
|
||||||
Ces mots reflètent l'importance que le **Dr. José Benjamín Pérez Matos** attribue au calendrier politique israélien dans le contexte régional. Dans cette perspective, le temps disponible pour consolider certaines décisions stratégiques est limité et pourrait être conditionné par le résultat des prochaines élections.
|
|
||||||
|
|
||||||
Comme l'a souligné le **Dr. José Benjamín Pérez Matos** lui-même : « la marge de manœuvre pour consolider les positions de force est extrêmement étroite. » Les acteurs politiques doivent agir avec promptitude face à la possibilité d'un retournement électoral ou d'une surprise dans les urnes.
|
|
||||||
|
|
||||||
Cet avertissement constitue la conclusion naturelle de l'analyse géopolitique développée tout au long de cette réflexion. Cependant, pour le **Dr. José Benjamín Pérez Matos**, les événements internationaux ne peuvent pas être compris uniquement sous l’angle des décisions humaines, de la diplomatie ou de la stratégie militaire.
|
|
||||||
|
|
||||||
Au-delà de tous ces facteurs, il existe un dessein supérieur dont l'accomplissement, affirme-t-il, continue de s’accomplir conformément au programme prophétique révélé dans les Écritures.
|
|
||||||
|
|
||||||
C'est pourquoi il a conclu son exposé en rappelant :
|
|
||||||
|
|
||||||
**«Mais rappelez-vous que tout est, et tout s'accomplira, conformément aux prophéties. Rien de tout cela ne reste entre les mains des hommes».**
|
|
||||||
|
|
||||||
Selon la perspective présentée par le **Dr. José Benjamín Pérez Matos**, les événements qui se déroulent aujourd'hui au Moyen-Orient transcendent la conjoncture internationale et constituent une part d'un processus historique de plus grande envergure. Au-delà des négociations diplomatiques, des décisions militaires ou des changements politiques qui peuvent se produire dans les différents pays impliqués, le dénouement définitif sera déterminé par l'accomplissement du dessein prophétique qui, selon les Écritures, conduira à l'établissement de l'ordre final annoncé dans le livre de Daniel.
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
locale: pt
|
|
||||||
title: 'A verdadeira natureza das ideias'
|
|
||||||
date: 2026-06-29
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-06-29-a-verdadeira-natureza-das-ideias
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# A verdadeira natureza das ideias
|
|
||||||
|
|
||||||
As campanhas eleitorais costumam estar carregadas de promessas, slogans e discursos cuidadosamente elaborados para conquistar o voto do cidadão. No entanto, uma vez encerrada a disputa política, chega o momento em que as ideias deixam o plano teórico e começam a se manifestar na realidade. Sustento firmemente que é exatamente nesse momento que se torna possível conhecer a verdadeira natureza de uma ideologia: não pelo que promete, mas pela conduta que desperta em seus dirigentes, em seus militantes e naqueles que atuam em seu nome.
|
|
||||||
|
|
||||||
As ideologias não devem ser julgadas pela beleza de seus discursos, e sim por seus resultados concretos.
|
|
||||||
|
|
||||||
Sob essa perspectiva, um dos indicadores mais claros consiste em observar como os diferentes setores políticos reagem quando perdem o poder ou quando o resultado de uma eleição lhes é desfavorável. Em diversos países da América Latina — como Chile, Bolívia, Honduras e Equador — observa-se um fenômeno que se repete com frequência: quando um governo de esquerda é substituído por um de direita, a resposta não é a aceitação institucional, e sim a agitação, os distúrbios e as ações destinadas a alterar a ordem pública. Em contrapartida, quando os resultados eleitorais favorecem a esquerda, a normalidade prevalece. A direita, em sua grande maioria, aceita os resultados e respeita a ordem sem recorrer à violência como instrumento de pressão política; os poucos distúrbios isolados provêm de indivíduos imprudentes ou de provocadores infiltrados com o objetivo de gerar desestabilização.
|
|
||||||
|
|
||||||
Essa profunda diferença e assimetria moral se manifesta com total clareza na segurança dos líderes durante as disputas políticas.
|
|
||||||
|
|
||||||
Recordo perfeitamente as duras críticas dirigidas ao presidente da Colômbia por comparecer a seus comícios cercado de rigorosas medidas de proteção e blindagem, utilizando isso para apresentá-lo como alguém medroso. No entanto, esse dirigente precisava proteger sua vida porque havia ameaças concretas de morte contra ele. Em contrapartida, o candidato de esquerda caminhava livremente e sem receios. A explicação é pura lógica: seus seguidores jamais atentariam contra seu próprio líder, e nós, dos setores da direita, não somos assassinos nem utilizamos a eliminação física do adversário como ferramenta de ação política. É nessa necessidade de proteção que se evidencia em que lado se encontra a inclinação para o dano e para o mal.
|
|
||||||
|
|
||||||
Não se trata de generalizar de forma absoluta; reconheço que nem todos os que se identificam com a esquerda participam dessas condutas. Muitos cidadãos apoiam esses movimentos de boa-fé, convencidos de que representam um caminho para uma sociedade mais justa. Contudo, marcham enganados por propostas ideológicas que prometem justiça social, mas ignoram por completo quais são suas consequências reais.
|
|
||||||
Os exemplos que a nossa região nos apresenta são dolorosos, evidentes e não deixam margem para discussão.
|
|
||||||
|
|
||||||
Cuba, que em seu tempo foi uma das ilhas mais prósperas e avançadas do continente, hoje afunda em uma profunda deterioração econômica e social, carecendo, inclusive, de serviços básicos, como o fornecimento de energia elétrica. O mesmo roteiro de destruição institucional e econômica foi seguido pela Nicarágua e pela Venezuela.
|
|
||||||
|
|
||||||
Esta última nação se encontra hoje em uma transição crucial, e meu desejo ardente é que esse processo se complete plenamente para que o povo venezuelano rompa suas correntes, recupere suas instituições democráticas e volte a viver em absoluta e total liberdade.
|
|
||||||
|
|
||||||
A história recente oferece exemplos suficientes para avaliar cada modelo; por isso, reafirmo minha convicção de que a defesa da liberdade, do Estado de Direito e da convivência pacífica são pilares indispensáveis para construir sociedades verdadeiramente prósperas.
|
|
||||||
|
|
||||||
**Dr. José Benjamín Pérez Matos**<br>
|
|
||||||
Presidente<br>
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
---
|
|
||||||
locale: pt
|
|
||||||
title: 'Paz temporária ou o início de uma reconfiguração global no Oriente Médio?'
|
|
||||||
date: 2026-07-26
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-07-26-paz-temporaria-ou-o-inicio-de-uma-reconfiguracao-global-no-oriente-medio
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# Paz temporária ou o início de uma reconfiguração global no Oriente Médio?
|
|
||||||
|
|
||||||
Os acontecimentos das últimas semanas no Oriente Médio voltaram a colocar a região no centro da atenção internacional. A recente pausa nos bombardeios dos Estados Unidos sobre o território iraniano, após quase duas semanas de hostilidades contínuas, abriu um compasso de espera que muitos analistas apresentam como um possível avanço rumo a uma etapa de diplomacia estratégica.
|
|
||||||
|
|
||||||
As conversas técnicas realizadas em Omã e os esforços voltados para estabilizar o trânsito pelo Estreito de Ormuz parecem refletir a intenção de reduzir a tensão e evitar uma escalada que comprometa ainda mais a estabilidade regional e o comércio internacional.
|
|
||||||
|
|
||||||
No entanto, para o **Dr. José Benjamín Pérez Matos**, por trás desses movimentos diplomáticos existe uma realidade muito mais profunda e transcendente, que não pode ser compreendida apenas sob a perspectiva da política internacional.
|
|
||||||
|
|
||||||
Ao referir-se ao momento vivido pela região, expressou:
|
|
||||||
|
|
||||||
**«Agora, nestes dias, os Estados Unidos ainda têm essa guerra aí com o Irã; e a última coisa que ouvi: que parece que vão parar por aí, quando deveriam exterminar por completo, pela raiz, o problema! Se continuarem lançando duas bombinhas e recuarem, eles vão, mais adiante, fazer o mesmo. Veem? São processos aparentemente de paz temporária, mas o mal continua lá»**.
|
|
||||||
|
|
||||||
Essas palavras convidam a distinguir entre uma paz circunstancial e a eliminação definitiva das causas que dão origem ao conflito. Sob essa perspectiva, uma interrupção temporária das operações militares não constitui necessariamente a resolução do problema, mas apenas uma pausa dentro de um processo que ainda permanece em aberto.
|
|
||||||
|
|
||||||
A própria evolução dos acontecimentos internacionais confirma a fragilidade do cenário atual.
|
|
||||||
|
|
||||||
Enquanto o Exército dos Estados Unidos suspendeu seus ataques aéreos após treze noites consecutivas de bombardeios, a incerteza continua predominando na comunidade internacional. O cenário permanece em aberto, e as principais potências seguem avaliando os próximos passos em uma região cuja estabilidade continua sendo determinante para o equilíbrio geopolítico mundial.
|
|
||||||
|
|
||||||
Nesse contexto, o presidente dos Estados Unidos, Donald Trump, tem mantido uma postura que combina a pressão diplomática com a possibilidade de alcançar um entendimento com Teerã.
|
|
||||||
|
|
||||||
Por um lado, fez severas advertências ao regime iraniano; por outro, alimentou publicamente as expectativas de uma negociação ao afirmar, diante da imprensa reunida no Salão Oval:
|
|
||||||
|
|
||||||
«Podemos negociar com eles, o que também estamos fazendo neste momento».
|
|
||||||
|
|
||||||
No entanto, o próprio mandatário também moderou essas expectativas ao declarar que não considera que o Irã ainda esteja “ready (ou pronto)” para alcançar um acordo definitivo.
|
|
||||||
|
|
||||||
Ao mesmo tempo, reconheceu:
|
|
||||||
|
|
||||||
«Acho que eles estão ficando cada vez mais sérios com o passar dos dias, talvez por uma razão óbvia».
|
|
||||||
|
|
||||||
As declarações do presidente norte-americano refletem um cenário em que continuam coexistindo a pressão militar, a negociação diplomática e a incerteza quanto ao desfecho definitivo do conflito.
|
|
||||||
|
|
||||||
## O pano de fundo profético da crise
|
|
||||||
|
|
||||||
Para o **Dr. José Benjamín Pérez Matos**, compreender plenamente o que ocorre entre Washington e Teerã exige elevar o olhar acima da simples cobertura jornalística e analisar os acontecimentos sob uma perspectiva mais ampla.
|
|
||||||
|
|
||||||
Nesse sentido, sustentou que é necessário observar o mapa geopolítico por meio da lente das profecias bíblicas contidas no capítulo 2 do livro de Daniel. Nesse contexto, afirmou:
|
|
||||||
|
|
||||||
**«Esse reino da Pérsia, esse reino do Irã, tem que ser removido completamente, para que permaneça somente o reino de Roma; ou seja, o reino dos pés de ferro e barro cozido»**.
|
|
||||||
|
|
||||||
Sob essa perspectiva teológica, a ordem mundial final não contempla a coexistência de diferentes blocos geopolíticos que se desenvolvam simultaneamente como estruturas paralelas de poder.
|
|
||||||
|
|
||||||
Como explicou o **Dr. José Benjamín Pérez Matos**:
|
|
||||||
|
|
||||||
**«Não pode haver também um reino correndo em paralelo com esse último reino das pernas de ferro e barro cozido; somente esse tem que permanecer. Portanto, esses resíduos que estão ficando desse império da Pérsia: Irã, têm que ser removidos. E isso é um sinal muito grande, quando isso acontecer. Será um marco profético definitivo nestes dias».**
|
|
||||||
|
|
||||||
A partir dessa interpretação, os acontecimentos atuais transcendem o âmbito estritamente político e militar para inserir-se em um processo histórico de maior alcance, cujo desenvolvimento, segundo o **Dr. José Benjamín Pérez Matos**, faz parte do cumprimento progressivo das profecias bíblicas.
|
|
||||||
|
|
||||||
## Diplomacia de alta pressão na Casa Branca
|
|
||||||
|
|
||||||
É precisamente nesse cenário de máxima tensão que a visita do primeiro-ministro do Estado de Israel, Benjamin Netanyahu, aos Estados Unidos adquire especial relevância.
|
|
||||||
|
|
||||||
Embora o motivo oficial da viagem seja participar das homenagens fúnebres ao falecido senador Lindsey Graham — descrito pelo Gabinete do Primeiro-Ministro como “um amigo de Israel” —, as reuniões previstas entre as mais altas autoridades de ambos os países terão como eixo o futuro imediato do Oriente Médio e os desafios estratégicos enfrentados pela região.
|
|
||||||
|
|
||||||
Ao referir-se a esses encontros, o **Dr. José Benjamín Pérez Matos** declarou:
|
|
||||||
|
|
||||||
**«Agora, esperemos que... eles têm uma reunião nestes dias em Washington, ou em Nova York. O primeiro-ministro de Israel, Benjamin Netanyahu, vai estar lá; e também vão falar sobre tudo isso».**
|
|
||||||
|
|
||||||
A importância dessas conversas reside no fato de que Israel tem acompanhado com cautela o desenvolvimento dos ataques norte-americanos, plenamente consciente de que, nessa crise, está em jogo o controle de uma via marítima estratégica pela qual transita aproximadamente vinte por cento do petróleo comercializado no mundo.
|
|
||||||
|
|
||||||
Consequentemente, a retomada dos contatos bilaterais entre Washington e Jerusalém busca unificar critérios diante de um inimigo comum e coordenar os próximos passos estratégicos em um cenário marcado pela permanente volatilidade do golfo Pérsico.
|
|
||||||
|
|
||||||
|
|
||||||
## A corrida contra o relógio eleitoral
|
|
||||||
|
|
||||||
Além do componente militar e diplomático, o fator tempo aparece como um dos elementos mais sensíveis da conjuntura atual.
|
|
||||||
|
|
||||||
A proximidade dos próximos processos eleitorais introduz uma variável política que pode modificar significativamente o cenário geopolítico.
|
|
||||||
|
|
||||||
No plano interno dos Estados Unidos, o presidente Donald Trump minimizou as especulações sobre o eventual impacto eleitoral do aumento dos preços dos combustíveis.
|
|
||||||
Diante da imprensa, afirmou:
|
|
||||||
|
|
||||||
«Apesar do que todos dizem sobre a eleição, não tenho pressa... As eleições se resolvem por si mesmas».
|
|
||||||
|
|
||||||
No entanto, o **Dr. José Benjamín Pérez Matos** chamou a atenção para outro processo eleitoral que, sob sua perspectiva, reveste-se de importância ainda maior para o futuro imediato do Oriente Médio: as eleições previstas em Israel.
|
|
||||||
|
|
||||||
Sobre esse ponto, expressou:
|
|
||||||
|
|
||||||
**«Mas vejam o que acontece em Israel: agora vai haver eleições, em outubro. Eles têm que se apressar. Porque, se cair ali um primeiro-ministro que não esteja a favor (e nessa linha de pensamento) do mundo religioso, dos ortodoxos, e cair outro e ganhar as eleições em outubro, as coisas vão se tornar difíceis para Israel. Ou seja, é melhor aproveitar este período que ainda resta, caso aconteça alguma surpresa ali em outubro»**.
|
|
||||||
|
|
||||||
Essas palavras refletem a importância que o **Dr. José Benjamín Pérez Matos** atribui ao calendário político israelense dentro do contexto regional. Sob essa perspectiva, o tempo disponível para consolidar determinadas decisões estratégicas é limitado e poderá ser condicionado pelo resultado das próximas eleições.
|
|
||||||
|
|
||||||
Como apontou o próprio **Dr. José Benjamín Pérez Matos**:
|
|
||||||
|
|
||||||
**«A margem de manobra para consolidar as posições de força é extremamente estreita. Os atores políticos devem agir com rapidez diante da possibilidade de uma reviravolta eleitoral ou de uma surpresa nas urnas».**
|
|
||||||
|
|
||||||
Essa advertência constitui o encerramento natural da análise geopolítica desenvolvida ao longo desta reflexão. No entanto, para o **Dr. José Benjamín Pérez Matos**, os acontecimentos internacionais não podem ser compreendidos apenas sob a perspectiva das decisões humanas, da diplomacia ou da estratégia militar.
|
|
||||||
|
|
||||||
Acima de todos esses fatores existe um propósito superior, cujo cumprimento, afirma, continua desenvolvendo-se conforme o programa profético revelado nas Escrituras.
|
|
||||||
|
|
||||||
Por isso, concluiu sua exposição recordando:
|
|
||||||
|
|
||||||
**«Mas recordem que tudo é, e tudo se cumprirá, conforme as profecias. Nada disso fica nas mãos humanas».**
|
|
||||||
|
|
||||||
Sob a perspectiva apresentada pelo **Dr. José Benjamín Pérez Matos**, os acontecimentos que hoje se desenvolvem no Oriente Médio transcendem a conjuntura internacional e constituem parte de um processo histórico de maior alcance. Para além das negociações diplomáticas, das decisões militares ou das mudanças políticas que possam ocorrer nos diferentes países envolvidos, o desfecho definitivo corresponderá ao cumprimento do propósito profético que, segundo as Escrituras, conduzirá ao estabelecimento da ordem final anunciada no livro de Daniel.
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
---
|
|
||||||
locale: rw
|
|
||||||
title: Amahoro y'igihe gito cyangwa intangiriro yo kongera gutunganya gahunda y'Isi mu Burasirazuba bwo Hagati?
|
|
||||||
date: 2026-07-26
|
|
||||||
order: 1
|
|
||||||
# city: 'Palmira'
|
|
||||||
# country: 'CO'
|
|
||||||
# state: 'Valle del Cauca'
|
|
||||||
slug: 2026-07-26-amahoro-y-igihe-gito-cyangwa-intangiriro-yo-kongera-gutunganya-gahunda-y-isi-mu-burasirazuba-bwo-hagati
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,q-100/comunicado-1.webp'
|
|
||||||
# tags: [Comunicado, Venezuela, Estados Unidos]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred,q-70/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
# Amahoro y'igihe gito cyangwa intangiriro yo kongera gutunganya gahunda y'Isi mu Burasirazuba bwo Hagati?
|
|
||||||
|
|
||||||
Mu byumweru bishize, ibyabaye mu Burasirazuba bwo Hagati byongeye gushyira ako karere mu rwego rw'ibiri kwitabwaho cyane ku rwego mpuzamahanga. Guhagarara by'agateganyo kw'ibitero bya Leta Zunze Ubumwe za Amerika ku butaka bwa Irani, nyuma y'ibyumweru hafi bibiri by'imirwano idahagarara, byafunguye igihe cyo gutegereza, aho abasesenguzi benshi babibona nk'intambwe ishobora kuganisha ku rwego rw'ububanyi n'amahanga bushingiye ku ngamba z'igihe kirekire.
|
|
||||||
|
|
||||||
Ibiganiro bya tekiniki byabereye muri Oman, hamwe n'imbaraga zigamije gushimangira umutekano w'ubwikorezi bunyura mu muhora wa Ormuz, bigaragara ko bigamije kugabanya umwuka mubi no kwirinda ko amakimbirane yarushaho gukaza umurego, ibintu byarushaho guhungabanya umutekano w'akarere ndetse n'ubucuruzi mpuzamahanga.
|
|
||||||
|
|
||||||
Ariko, kuri **Dr. José Benjamín Pérez Matos**, inyuma y'izo ngamba z'ububanyi n'amahanga hari ukuri kwimbitse kandi kw'ingirakamaro kurushaho, kudashobora gusobanurwa gusa hashingiwe ku miterere ya politiki mpuzamahanga.
|
|
||||||
Agaruka ku bihe ako karere karimo kunyuramo, yagize ati:
|
|
||||||
|
|
||||||
**«None rero, muri iyi minsi Leta Zunze Ubumwe za Amerika iracyafite iyo ntambara na Irani; kandi icyo numvise bwa nyuma ni uko bigaragara ko bazabihagararaho. Nyamara bagombaga kurandura burundu icyo kibazo, bagihereye mu mizi! Nibakomeza kujugunya ibisasu bibiri gusa hanyuma bakikuramo, nyuma bazongera gukora nk'ibyo. Murabona? Bigaragara nk'ibikorwa by'amahoro y'igihe gito, ariko ikibi kiracyariho.»**
|
|
||||||
|
|
||||||
Aya magambo aduhamagarira gutandukanya amahoro y'igihe gito n'ikorwa ryo gukuraho burundu impamvu zitera amakimbirane. Dukurikije iyo myumvire, guhagarika ibikorwa bya gisirikare by'agateganyo ntibivuze byanze bikunze ko ikibazo cyakemutse, ahubwo ni ikiruhuko cy'igihe gito mu nzira y'ibikorwa bitararangira.
|
|
||||||
|
|
||||||
Imigendekere ubwayo y'ibyabaye ku rwego mpuzamahanga yemeza uburyo uko ibintu bimeze ubu bidafite gihamya yo kuramba.
|
|
||||||
|
|
||||||
Mu gihe ingabo za Leta Zunze Ubumwe za Amerika zahagaritse ibitero byazo byo mu kirere nyuma y'amajoro cumi n'atatu akurikirana y'ibisasu, ugushidikanya gukomeje kwiganje mu muryango mpuzamahanga. Imiterere y'ibintu iracyafunguye, kandi ibihugu bikomeye bikomeje gusuzuma intambwe zikurikira, mu karere umutekano wako ugikomeje kugira uruhare rukomeye mu kuringaniza imbaraga za politiki y'Isi.
|
|
||||||
|
|
||||||
Muri uru rwego, Perezida wa Leta Zunze Ubumwe za Amerika, Donald Trump, yakomeje gufata umwanya uhuza igitutu cya dipolomasi n'icyizere cyo kugera ku bwumvikane na Tehran.
|
|
||||||
|
|
||||||
Ku ruhande rumwe, yatanze imiburo ikomeye ku butegetsi bwa Irani; ku rundi ruhande, yeruye yagaragaje icyizere cy'uko hashobora kubaho ibiganiro, ubwo yabwiraga itangazamakuru ryari ryateraniye mu Biro bya Oval ati:
|
|
||||||
|
|
||||||
«Dushobora kugirana ibiganiro na bo, kandi ni na byo turimo gukora muri aka kanya.»
|
|
||||||
|
|
||||||
Ariko kandi, uwo muyobozi ubwe yagabanyije icyo cyizere avuga ko atabona ko Irani “yiteguye” kugeza ubu kugera ku masezerano ya nyuma.
|
|
||||||
|
|
||||||
Muri icyo gihe kandi, yemeye ko:
|
|
||||||
|
|
||||||
«Ntekereza ko bagenda barushaho gukomera ku cyemezo uko iminsi igenda ishira; wenda kubera impamvu igaragara.»
|
|
||||||
|
|
||||||
Amagambo ya Perezida wa Leta Zunze Ubumwe za Amerika agaragaza imiterere y'ibintu aho igitutu cya gisirikare, ibiganiro bya dipolomasi, ndetse no kudasobanuka ku iherezo ry'amakimbirane bikomeje kubana hamwe.
|
|
||||||
|
|
||||||
Imvano y'ubuhanuzi y'ikibazo
|
|
||||||
|
|
||||||
Kuri **Dr. José Benjamín Pérez Matos**, gusobanukirwa neza ibiri kuba hagati ya Washington na Tehran bisaba kureba birenze amakuru asanzwe atangwa n'itangazamakuru, ahubwo hakigwa ibyabaye hifashishijwe imyumvire yagutse kurushaho.
|
|
||||||
|
|
||||||
Muri ubwo buryo, yavuze ko ari ngombwa kureba ikarita ya geopolitiki binyuze mu ndorerwamo y'ubuhanuzi bwa Bibiliya buboneka mu gice cya 2 cy'igitabo cya Daniyeli. Muri urwo rwego yagize ati:
|
|
||||||
|
|
||||||
**«Uwo bwami bw'u Buperesi, ubwo bwami bwa Irani, bugomba gukurwaho burundu, kugira ngo hasigare gusa ubwami bw'i Roma; ni ukuvuga ubwami bw'amaguru y'icyuma n'ibumba ryokeje.»**
|
|
||||||
|
|
||||||
Muri iyi myumvire ishingiye ku by'iyobokamana, gahunda y'Isi ya nyuma ntiteganya ko habaho ibice bitandukanye bya geopolitiki bizakomeza kubaho icyarimwe nk'imyubakire y'imbaraga zigereranywa.
|
|
||||||
|
|
||||||
Nk'uko **Dr. José Benjamín Pérez Matos** yabisobanuye:
|
|
||||||
|
|
||||||
**«Nta bundi bwami bushobora kubaho kandi ngo bugendere hamwe n'ubwo bwami bwa nyuma bw'amaguru y'icyuma n'ibumba ryokeje; bugomba gusigara ari bwo bwonyine. Ni yo mpamvu ibisigazwa bisigaye by'ubwo bwami bw'u Buperesi: Irani, bigomba gukurwaho. Kandi ibyo ni ikimenyetso gikomeye cyane, igihe ibyo bizaba bibaye. Ibyo bizashyiraho ikimenyetso gikomeye cya nyuma mu buhanuzi muri iyi minsi.»**
|
|
||||||
|
|
||||||
Dukurikije ubu busobanuro, ibyabaye muri iki gihe birenze urwego rwa politiki n'igisirikare gusa, ahubwo biri mu murongo w'amateka manini kurushaho, aho, nk'uko **Dr. José Benjamín Pérez Matos** abivuga, iterambere ryabyo rigize igice cyo gusohora buhoro buhoro k'ubuhanuzi bwa Bibiliya.
|
|
||||||
|
|
||||||
## Dipolomasi y'igitutu gikomeye muri White House
|
|
||||||
|
|
||||||
Ni muri uru rwego rw'ubushyamirane bukabije ni ho uruzinduko rwa Minisitiri w'Intebe wa Leta ya Isirayeli, Benjamín Netanyahu, muri Leta Zunze Ubumwe za Amerika ruboneramo umwanya wihariye.
|
|
||||||
|
|
||||||
Nubwo impamvu yatangajwe ku mugaragaro y'urwo rugendo ari ukwitabira umuhango wo gushyingura no gusezera kuri senateri witabye Imana Lindsey Graham — wasobanuwe n'Ibiro bya Minisitiri w'Intebe nk’ “inshuti ya Isirayeli” — ibiganiro biteganyijwe hagati y'abayobozi bakuru b'ibihugu byombi bizibanda ku hazaza hihuse h'Uburasirazuba bwo Hagati ndetse n'ibibazo by'ingamba akarere gahura na byo.
|
|
||||||
|
|
||||||
Agaruka kuri ibyo biganiro, **Dr. José Benjamín Pérez Matos** yagize ati:
|
|
||||||
|
|
||||||
**«Noneho, reka dutegereze ko… muri iyi minsi hari inama izabera i Washington cyangwa i New York. Minisitiri w’Intebe wa Isirayeli, Benjamín Netanyahu, azaba ahari; kandi bazaganira kuri ibyo byose na byo.»**
|
|
||||||
|
|
||||||
Iby'ingenzi muri ibi biganiro ni uko Isirayeli yakurikiranye yitonze uko ibitero bya Leta Zunze Ubumwe za Amerika byagenze, izi neza ko muri iki kibazo harimo kugenzura inzira y'ingenzi y'ubwikorezi bwo mu nyanja inyuramo hafi makumyabiri ku ijana bya peteroli icuruzwa ku isi.
|
|
||||||
|
|
||||||
Kubera iyo mpamvu, kongera gutangiza ibiganiro hagati ya Washington na Yerusalemu bigamije guhuza imyumvire ku birebana n'umwanzi bahuriyeho, no guhuza ingamba zizakurikiraho mu rwego rw'ubutabazi n'umutekano, mu bihe birangwa n'ihindagurika ridahoraho mu Karere k'Ikigobe cy'u Buperesi.
|
|
||||||
|
|
||||||
## Irushanwa ryo guhangana n'igihe mbere y'amatora.
|
|
||||||
Uretse ibijyanye n'igisirikare n'ububanyi n'amahanga, ikintu cy'igihe na cyo kigaragara nk'imwe mu ngingo zikomeye kandi zifite uburemere muri ibi bihe.
|
|
||||||
|
|
||||||
Kuba amatora ateganyijwe yegereje byinjiza indi ngingo ya politiki ishobora guhindura ku buryo bugaragara imiterere y'ibibera mu rwego rwa geopolitiki.
|
|
||||||
|
|
||||||
Muri Leta Zunze Ubumwe za Amerika, Perezida Donald Trump yagaragaje ko adaha agaciro ibitekerezo bivuga ko izamuka ry'ibiciro by'ibikomoka kuri peteroli rishobora kugira ingaruka ku matora ari imbere.
|
|
||||||
|
|
||||||
Imbere y'itangazamakuru, yagize ati:
|
|
||||||
|
|
||||||
"N'ubwo abantu bose bavuga iby'amatora, ntabwo nihuta... Amatora azikemurira ubwayo."
|
|
||||||
|
|
||||||
Nyamara, **Dr. José Benjamín Pérez Matos** yagaragaje ko hari indi gahunda y'amatora, nk'uko abibona, ifite akamaro karenze ako ku hazaza ha vuba h'Uburasirazuba bwo Hagati: amatora ateganyijwe muri Isirayeli.
|
|
||||||
|
|
||||||
Kuri iyo ngingo yagize ati:
|
|
||||||
|
|
||||||
**"Ariko nimurebe ibibera muri Isirayeli: ubu hagiye kuba amatora mu kwezi k'Ukwakira. Bagomba kwihutira gukora ibyo bagomba gukora. Kuko nihaza Minisitiri w'Intebe udashyigikiye (cyangwa udakurikiza uwo murongo w'ibitekerezo) w'itsinda ry'amadini n'Abayahudi b'aba-Orutodogisi, maze hakaza undi agatsinda ayo matora yo mu Ukwakira, ibintu bizakomera kuri Isirayeli. Ni ukuvuga ko bakwiriye kubyaza umusaruro iki gihe gisigaye cya manda, mu gihe haba havutse impinduka itunguranye muri ayo matora yo mu Ukwakira.”**
|
|
||||||
|
|
||||||
Aya magambo agaragaza akamaro **Dr. José Benjamín Pérez Matos** aha ingengabihe ya politiki ya Isirayeli mu rwego rw'ibibera mu karere. Dukurikije uko abibona, igihe gisigaye cyo gushimangira imyanzuro imwe n'imwe y'ingenzi mu rwego rw'ingamba ni gito cyane, kandi gishobora guterwa impinduka n'ibizava mu matora ateganyijwe.
|
|
||||||
|
|
||||||
Nk'uko **Dr. José Benjamín Pérez Matos** ubwe yabivuze:
|
|
||||||
|
|
||||||
"Igihe gisigaye cyo gushimangira imyanya y'imbaraga ni gito cyane. Abanyapolitiki bagomba gukora bihuse, bitewe n'uko hashobora kubaho ihinduka ritunguranye ry'ibyavuye mu matora cyangwa igitunguranye mu matora.”
|
|
||||||
|
|
||||||
Uyu muburo ni wo usoza mu buryo busanzwe isesengura rya geopolitiki ryatanzwe muri iki gitekerezo. Nyamara, kuri **Dr. José Benjamín Pérez Matos**, ibyabaye n'ibirimo kuba ku rwego mpuzamahanga ntibishobora gusobanurwa gusa hashingiwe ku byemezo by'abantu, ububanyi n'amahanga cyangwa ingamba za gisirikare.
|
|
||||||
|
|
||||||
Hejuru y'izo ngingo zose, avuga ko hari umugambi urenze byose, ukomeje gusohora nk'uko gahunda y'ubuhanuzi yahishuwe mu Byanditswe Byera ibiteganya.
|
|
||||||
|
|
||||||
Ni yo mpamvu yasoreje inyigisho ye yibutsa ati:
|
|
||||||
|
|
||||||
**"Ariko mwibuke ko ibintu byose ari, kandi byose bizasohora nk'uko ubuhanuzi buri. Nta na kimwe muri ibi kiri mu maboko y'abantu.”**
|
|
||||||
|
|
||||||
Dukurikije imyumvire yatanzwe na **Dr. José Benjamín Pérez Matos**, ibibera muri iki gihe mu Burasirazuba bwo Hagati birenze ibibazo by'igihe gito byo ku rwego mpuzamahanga, ahubwo biri mu bigize inzira y'amateka ifite urugero runini kurushaho. Uretse ibiganiro by'ububanyi n'amahanga, ibyemezo bya gisirikare cyangwa impinduka za politiki zishobora kubaho mu bihugu bitandukanye birebwa n'ibi bibazo, iherezo rizasubiza ku isohozwa ry'umugambi w'ubuhanuzi, nk'uko avuga ko Ibyanditswe bibigaragaza, uzageza ku gushyirwaho k'ubutegetsi bwa nyuma bwatangajwe mu gitabo cya Daniyeli.
|
|
||||||
|
|
@ -2,11 +2,10 @@
|
||||||
locale: en
|
locale: en
|
||||||
title: 'A New Son for Jacareí: The Tribute to Dr. José Benjamín Pérez Matos'
|
title: 'A New Son for Jacareí: The Tribute to Dr. José Benjamín Pérez Matos'
|
||||||
slug: a-new-son-for-jacarei-the-tribute-to-dr-jose-benjamin-perez-matos
|
slug: a-new-son-for-jacarei-the-tribute-to-dr-jose-benjamin-perez-matos
|
||||||
date: 2025-08-29
|
date: 2025-09-05
|
||||||
place: The basement
|
place: The basement
|
||||||
city: Jacareí
|
city: Jacareí
|
||||||
country: BR
|
country: BR
|
||||||
tags: [Brazil]
|
|
||||||
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg?updatedAt=1770780193361
|
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg?updatedAt=1770780193361
|
||||||
gallery: [
|
gallery: [
|
||||||
{
|
{
|
||||||
|
|
@ -15,10 +14,6 @@ gallery: [
|
||||||
]
|
]
|
||||||
---
|
---
|
||||||
|
|
||||||
# A New Son for Jacareí: The Tribute to Dr. José Benjamín Pérez Matos
|
|
||||||
|
|
||||||
*Jacareí, Brazil – August 29, 2025*
|
|
||||||
|
|
||||||
The city of Jacareí, in the state of São Paulo, Brazil, woke up with a different atmosphere, as if its streets—dressed in history, trees and palm trees—knew that someone special was coming to wander them, not as a tourist, but as a future adopted son.
|
The city of Jacareí, in the state of São Paulo, Brazil, woke up with a different atmosphere, as if its streets—dressed in history, trees and palm trees—knew that someone special was coming to wander them, not as a tourist, but as a future adopted son.
|
||||||
|
|
||||||
At around 1:15 p.m. on Friday the 29th of August, Dr. José Benjamín Pérez Matos, accompanied by his wife and an entourage, made his first stop at the imposing City Hall building (Prefeitura Municipal), the beating heart of local executive power.
|
At around 1:15 p.m. on Friday the 29th of August, Dr. José Benjamín Pérez Matos, accompanied by his wife and an entourage, made his first stop at the imposing City Hall building (Prefeitura Municipal), the beating heart of local executive power.
|
||||||
|
|
@ -37,7 +32,7 @@ The meeting ended with a serene and profound prayer by Dr. José Benjamín, who
|
||||||
|
|
||||||
**Jacareí Gains a Son and an Ambassador**
|
**Jacareí Gains a Son and an Ambassador**
|
||||||
|
|
||||||
A few meters away, the second act awaited. The Municipal Chamber of Jacareí, seat of the legislative branch, welcomed Dr. José Benjamín Pérez Matos at 1:30 p.m. in the Vereador Djalma D’Avila Leal auditorium. Councilwoman Maria Amélia was waiting for him there, who at that moment was giving statements to the local news program TV Câmara:
|
A few meters away, the second act awaited. The Câmara Municipal of Jacareí, seat of the legislative branch, welcomed Dr. Pérez Matos at 1:30 p.m. in the Vereador Djalma D’Avila Leal auditorium. Councilwoman Maria Amélia was waiting for him there, who at that moment was giving statements to the local news program TV Câmara:
|
||||||
|
|
||||||
“Since he was coming to Brazil, we immediately placed this proposal up for vote at home. All the governors approved it, and today we are here to make this symbolic presentation, because on his next visit to Brazil we intend to make this official presentation.”
|
“Since he was coming to Brazil, we immediately placed this proposal up for vote at home. All the governors approved it, and today we are here to make this symbolic presentation, because on his next visit to Brazil we intend to make this official presentation.”
|
||||||
|
|
||||||
|
|
@ -57,4 +52,4 @@ In the end, before the local press, Dr. José Benjamín summed up his feelings w
|
||||||
|
|
||||||
“Being a citizen of a city where you were not born is a joy, because there is one more place where you can become familiar with the culture and everything related to that city. I feel very honored to be a Jacareiense.”
|
“Being a citizen of a city where you were not born is a joy, because there is one more place where you can become familiar with the culture and everything related to that city. I feel very honored to be a Jacareiense.”
|
||||||
|
|
||||||
Thus concluded the visit to a city that opened its doors to a visitor who became a son. Since the age of 22, Dr. José Benjamín Pérez Matos has traveled throughout Brazil accompanying the Word of God. And today he adds Jacareí as a place he can call “home.”
|
Thus concluded the visit to a city that opened its doors to a visitor who became a son. Since the age of 22, Dr. Pérez Matos has traveled throughout Brazil accompanying the Word of God. And today he adds Jacareí as a place he can call “home.”
|
||||||
|
|
@ -2,10 +2,9 @@
|
||||||
locale: en
|
locale: en
|
||||||
title: 'Awarding of decoration: Order of Democracy Simón Bolívar'
|
title: 'Awarding of decoration: Order of Democracy Simón Bolívar'
|
||||||
date: 2025-05-08
|
date: 2025-05-08
|
||||||
slug: 2025-05-08-award-of-decoration-order-of-democracy-simon-bolivar
|
slug: awarding-of-decoration-order-of-democracy-simon-bolivar
|
||||||
city: Bogotá
|
city: Bogotá
|
||||||
country: CO
|
country: CO
|
||||||
tags: ['Colombia', 'Decoration']
|
|
||||||
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/JBP-CONDECORACION-25.webp?updatedAt=1770780239998
|
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/JBP-CONDECORACION-25.webp?updatedAt=1770780239998
|
||||||
gallery: [
|
gallery: [
|
||||||
{
|
{
|
||||||
|
|
@ -26,14 +25,14 @@ gallery: [
|
||||||
]
|
]
|
||||||
---
|
---
|
||||||
|
|
||||||
# Awarding of decoration: Order of Democracy Simón Bolívar
|
|
||||||
|
|
||||||
**Thursday, May 8, 2025
|
**Thursday, May 8, 2025
|
||||||
Bogotá, Colombia**
|
Bogotá, Colombia**
|
||||||
|
|
||||||
(Second activity)
|
(Second activity)
|
||||||
|
|
||||||
Dr. José Benjamín Pérez Matos
|
**Awarding of decoration: Order of Democracy Simón Bolívar**
|
||||||
|
|
||||||
|
Dr. Jose Benjamin Perez Matos
|
||||||
|
|
||||||
[The Order of Democracy Simón Bolívar, in the rank of Officer's Cross, is an official Colombian distinction awarded by the House of Representatives to citizens who have distinguished themselves in service to their country. It is a civil honor that recognizes the efforts, loyalty, and virtues of individuals or institutions that have contributed to democracy. The order was created in 1980 and has been awarded to a variety of figures and entities from the educational, scientific, military, civil, and political spheres, among others.]
|
[The Order of Democracy Simón Bolívar, in the rank of Officer's Cross, is an official Colombian distinction awarded by the House of Representatives to citizens who have distinguished themselves in service to their country. It is a civil honor that recognizes the efforts, loyalty, and virtues of individuals or institutions that have contributed to democracy. The order was created in 1980 and has been awarded to a variety of figures and entities from the educational, scientific, military, civil, and political spheres, among others.]
|
||||||
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
locale: es
|
|
||||||
title: 'Signs of a Global Transformation: Warnings About Israel and the Climate in the Middle East'
|
|
||||||
date: 2023-07-27
|
|
||||||
slug: 2023-07-27-signs-of-a-global-transformation-warnings-about-israel-and-the-climate-in-the-middle-east
|
|
||||||
place: ''
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/Lake-Urmia_NASA.-2.webp'
|
|
||||||
tags: [Iran, Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/Lake-Urmia_NASA.-2.webp',
|
|
||||||
text_alt: 'Lake Urmia in Iran in 2020 (left) and 2023 (right), after being desiccated by drought. NASA'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/new-042226-2.jpg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/new-042226-3.jpg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/new-042226-4.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Signs of a Global Transformation: Warnings About Israel and the Climate in the Middle East
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – July 27, 2023*
|
|
||||||
|
|
||||||
As part of an in-depth analysis of the current international situation, Dr. José Benjamín Pérez Matos discussed a series of events that, in his view, reflect a large-scale transformation in the history of mankind. His statements focused both on the internal situation in Israel and on the extreme weather events affecting the Middle East, drawing a connection between the two as signs of a larger process currently underway.
|
|
||||||
|
|
||||||
Dr. Pérez Matos pointed out that these changes should not be viewed as isolated events, but rather as part of a phase that is beginning gradually, and is destined to evolve into situations of even greater magnitude.
|
|
||||||
|
|
||||||
As for Israel, the analysis highlighted the level of social instability the country is currently experiencing, marked by protests and internal tensions that, according to the statements, are unprecedented in recent times:
|
|
||||||
|
|
||||||
**“Israel, on the other hand, look at all the things that are happening there in Israel, all those protests and everything, which have never happened there in Israel in recent times.”**
|
|
||||||
|
|
||||||
The assessment also included a direct reference to the climate crisis, particularly to the extreme temperatures recorded in Iran, which were interpreted as a warning of even more severe conditions in the future:
|
|
||||||
|
|
||||||
**“The sun as well, in Iran, they are saying it has already reached a certain temperature: 150 °F (I think it is), which is about the limit a human being can endure, something like that; the heat is already reaching those levels. But remember that the Scripture says that the sun will give off, will become about seven times hotter. So, imagine, if the sun is like that now, what will it be like in the time of tribulation?! What will come upon the human race is something terrible.”**
|
|
||||||
|
|
||||||
These statements offer a holistic assessment of the present, in which political, social, and environmental events are interconnected under a single interpretive framework. In this regard, Dr. Pérez Matos emphasizes the need to monitor these processes carefully, recognizing that they are part of a broader structural shift that will affect all of mankind.
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Diplomatic Alert in Latin America: Warning of Consequences Following the Severing of Ties with Israel'
|
|
||||||
date: 2023-11-01
|
|
||||||
slug: 2023-11-01-diplomatic-alert-in-latin-america-warning-of-consequences-following-the-severing-of-ties-with-israel
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-08_12-15-10.jpg'
|
|
||||||
tags: [Israel, Puerto Rico, Bolivia, Chile, Colombia]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-08_12-15-10.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Diplomatic Alert in Latin America: Warning of Consequences Following the Severing of Ties with Israel
|
|
||||||
|
|
||||||
***From Puerto Rico, Dr. José Benjamín Pérez Matos analyzed the regional geopolitical landscape and warned of the impact that countries adopting adverse positions toward Israel could face.***
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – November 1, 2023*
|
|
||||||
|
|
||||||
In an international context marked by the heightened geopolitical tension following the events of October 7, Dr. José Benjamín Pérez Matos, president of The Great Tent Cathedral, issued a firm warning regarding the diplomatic decisions that some countries of Latin America are adopting regarding the State of Israel.
|
|
||||||
|
|
||||||
During his remarks, the Puerto Rican leader focused on what he described as a distortion of the international narrative, in which —according to his analysis— an attempt is being made to invert the roles of the conflict. In this regard, he denounced the construction of a narrative that presents Israel as the aggressor, obscuring the true origin of the hostilities.
|
|
||||||
|
|
||||||
In parallel to that, Dr. José Benjamín Pérez Matos analyzed with concern the diplomatic shift beginning to arise from across the region, particularly in light of recent decisions such as Bolivia’s severing of ties with Israel. In that regard, he firmly expressed: **“I saw that Bolivia, I think it was another country that would be cutting ties with Israel, I’m not sure if they already did it. They’ve gotten themselves into serious trouble!”**
|
|
||||||
|
|
||||||
Once the measure was confirmed, he deepened his analysis with a direct warning: **“‘Bolivia cuts ties with Israel.’” In other words, we’re already seeing how all of that is happening. Imagine! In other words, there has to be a reason for them to receive what they have to receive.”**
|
|
||||||
|
|
||||||
Dr. José Benjamín Pérez Matos’ assertion did not stop at a specific analysis, but extended to a broader reading of the region’s strategic positioning. Within this framework, he maintained that foreign policy decisions regarding Israel are neither neutral nor isolated, but can carry profound consequences for the countries involved. In his words: **“We want Latin America to not suffer and to not face such disastrous consequences; but a country that goes against Israel, it says that ‘he who blesses you will be blessed, and he who curses you will be cursed.’”**
|
|
||||||
|
|
||||||
The analysis also included other countries in the region, particularly Chile and Colombia, in relation to their recent diplomatic decisions. On this matter, Dr. José Benjamín Pérez Matos referred to the moves made by both governments in recalling their ambassadors to Israel for consultations, interpreting these actions as part of a broader regional trend that, in his view, responds to wider external pressures.
|
|
||||||
|
|
||||||
From his perspective, this type of position reflects an international alignment that could carry significant consequences for the states that adopt them. In this regard, he warned of the risk that a series of cascading diplomatic decisions could give rise to a scenario of greater regional instability.
|
|
||||||
|
|
||||||
His closing message made clear a central concern: the impact that these decisions could have not only on the diplomatic level, but also on the political and strategic future of Latin America.
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Escalation Between Iran and Israel: Warnings of a Possible Change of Era in the Global Landscape'
|
|
||||||
date: 2024-04-13
|
|
||||||
slug: 2024-04-13-escalation-between-iran-and-israel-warnings-of-a-possible-change-of-era-in-the-global-landscape
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-08_12-42-30.jpg'
|
|
||||||
tags: [Israel, Iran]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-08_12-42-30.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Escalation Between Iran and Israel: Warnings of a Possible Change of Era in the Global Landscape
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – April 13, 2024*
|
|
||||||
|
|
||||||
The international landscape took a sharp turn in recent hours following the attack launched by Iran against Israel, a military escalation that sparked concern at a global level. In response, Dr. José Benjamín Pérez Matos addressed the situation from The Great Tent Cathedral, offering an interpretation of events through both a geopolitical and prophetic lens.
|
|
||||||
|
|
||||||
During his address, Dr. José Benjamín Pérez Matos described the immediacy and seriousness of the attack, referencing to the information that was being reported in real time:
|
|
||||||
|
|
||||||
**“Today, Saturday, April 13 of this year 2024, we have been watching the news —those who have been watching the news— of that attack that has been launched by Iran, where they have sent drones, different air strikes, which, according to the news, would be arriving within an hour, an hour and a half or two hours.”**
|
|
||||||
|
|
||||||
In his statement, he also highlighted the historic role of the Middle East as the epicenter of international tensions, underscoring the recurring nature of conflict in the region:
|
|
||||||
|
|
||||||
**“And aware that the Hebrew people have always been in these wars… because you see, the spark is always there in the Middle East. And we know that from one moment to another that Third World War will be unleashed.”**
|
|
||||||
|
|
||||||
Likewise, Dr. José Benjamín Pérez Matos presented that these events make up a broader transformational process, tied to a stage of transition of both historical and spiritual nature:
|
|
||||||
|
|
||||||
**“And there is a promise for Israel, where the Throne of David will be restored; for which there are a series of events that will be taking place in this change of kingdom, from the kingdom of the gentiles to the Kingdom of the Prince Messiah.”**
|
|
||||||
|
|
||||||
As the drones filled the sky and the tension grew by the minute, the international community observed with deep concern over the possibility of an escalation into a larger conflict. In that context, Dr. José Benjamín Pérez Matos concluded with a call to awareness and reflection on the events unfolding in real time, urging those present to keep a close eye on the situation in the Middle East and to keep prayer for the State of Israel.
|
|
||||||
|
|
||||||
Recent events reaffirm the volatile nature of the international landscape and the strategic centrality of the Middle East, in a space where every move can have global implications.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Message to Israel in Decisive Times: Support, and a Call to Wisdom'
|
|
||||||
date: 2024-04-15
|
|
||||||
slug: 2024-04-15-mensaje-a-israel-en-tiempos-decisivos-respaldo-y-llamado-a-la-sabiduria
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
|
|
||||||
tags: [Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Message to Israel in Decisive Times: Support, and a Call to Wisdom
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – april 15, 2024*
|
|
||||||
|
|
||||||
In an international context marked by growing tensions in the Middle East, **Dr. José Benjamín Pérez Matos** issued a message of support and blessing addressed to the people of Israel, highlighting the importance of decision-making at what he described as a key moment for the future of the region.
|
|
||||||
|
|
||||||
From Cayey, Puerto Rico, **Dr. José Benjamín Pérez Matos** addressed both the leaders and the Hebrew people, emphasizing the need to act with wisdom and responsibility in a highly complex environment:
|
|
||||||
|
|
||||||
**“May God bless Israel, may God bless the Hebrew people, and may they make the right decisions.”**
|
|
||||||
|
|
||||||
The message not only conveyed support, but also a perspective of hope connected to future events. In that regard, **Dr. José Benjamín Pérez Matos** expressed his desire that the people of Israel may receive with clarity and without delay that which, according to his vision, is drawing near:
|
|
||||||
|
|
||||||
**“May God place in their hearts that which they will soon receive.”**
|
|
||||||
|
|
||||||
These statements are part of a consistent message of support, in which faith and the spiritual dimension are presented as central elements of unity and guidance. Within this framework, the community that follows **Dr. José Benjamín Pérez Matos** reaffirms its support for Israel, emphasizing the role of prayer and conviction as factors that transcend borders.
|
|
||||||
|
|
||||||
The message issued from Puerto Rico thus joins a series of public statements underscoring the significance of the present moment, reinforcing a clear position of support and close attention to the development of events on the international stage.
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Israel’s Miracle After 76 Years: Sovereignty, Conflict, and the Projection of a Global Promise'
|
|
||||||
date: 2024-05-14
|
|
||||||
slug: 2024-05-14-israels-miracle-after-76-years-sovereignty-conflict-and-the-projection-of-a-global-promise
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
|
|
||||||
tags: [Puerto Rico, Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Israel’s Miracle After 76 Years: Sovereignty, Conflict, and the Projection of a Global Promise
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – May 14, 2024*
|
|
||||||
|
|
||||||
May 14 marks one of the most defining dates of the 20th century in geopolitical terms. Seventy-six years after the creation of the State of Israel, Dr. José Benjamín Pérez Matos offers a reading that goes beyond the traditional frameworks of international analysis, positioning the Hebrew nation not only as a central actor in the global system, but as the axis of a process of historical and transcendent scope.
|
|
||||||
|
|
||||||
From Cayey, the leader revisited the books developed by Dr. William Soto Santiago to interpret the very existence of Israel as an exceptional phenomenon. In his analysis, the continuity of the Israeli state—born in the wake of the Holocausts’ devastation—is not solely the result of political or military dynamics, but of a deeper logic that combines history, identity, and strategic vision.
|
|
||||||
|
|
||||||
## From International Resolution to State Consolidation
|
|
||||||
|
|
||||||
The starting point for this proposal is found in United Nations Resolution 181, passed in 1947, which paved the way for the creation of the State of Israel in 1948. Far from viewing it as an isolated event, Dr. José Benjamín Pérez Matos places it as the beginning of a sustained process of national reconstruction with global impact.
|
|
||||||
|
|
||||||
In that regard, he stated: **“Israel’s survival cannot be analyzed solely in political terms; we are witnessing the greatest miracle of the modern era, both politically and spiritually,”** emphasizing that the establishment of the State was not a circumstantial event, but rather the expression of a greater process.
|
|
||||||
|
|
||||||
The analysis acknowledges the historical upheavals of the Jewish people—including the loss of their territory in ancient times—but highlights that their return to the land in the 20th century represents a turning point that redefines their role in the contemporary international system.
|
|
||||||
|
|
||||||
## Israel at the Center of the International System
|
|
||||||
|
|
||||||
For Dr. José Benjamín Pérez Matos, Israel’s current positioning is no coincidence. Its political, technological, and military influence, combined with its constant presence on the global agenda, make it an unavoidable actor in any analysis of regional and global stability.
|
|
||||||
|
|
||||||
Beyond the ongoing tensions in the Middle East, his argument suggests that Israel functions as a **strategic node** where geopolitical interests, ideological disputes, and power dynamics on a global scale.
|
|
||||||
|
|
||||||
In this context, the city of Jerusalem takes on unique significance, not only as a political and religious center, but also as a constant point of reference for the international community.
|
|
||||||
|
|
||||||
## Strategic Expectations and Future Projections
|
|
||||||
|
|
||||||
One of the most significant aspects of this argument is the idea that Israel is currently undergoing a period of **“strategic expectation,”** in which, despite ongoing conflicts, a greater change is taking shape.
|
|
||||||
|
|
||||||
On this point, Dr. José Benjamín Pérez Matos affirmed: **“Israel is at a moment of strategic expectation. Everything points to a decisive sign that will mark the beginning of a new stage in its history,”** introducing the notion of a process that is still unfinished, but underway.
|
|
||||||
|
|
||||||
This interpretation takes the Israeli situation beyond the current situation, placing it within a dynamic of transformation that, according to his vision, will have global repercussions.
|
|
||||||
|
|
||||||
## A Key Player in an Uncertain Scenario
|
|
||||||
|
|
||||||
In an international context characterized by volatile alliances, prolonged conflicts, and reconfigurations of power, Dr. José Benjamín Pérez Matos takes a clear stance: Israel cannot be regarded solely as a State in conflict, but rather as a structural player in the international order.
|
|
||||||
|
|
||||||
In his closing remarks, he synthesized this vision: **“Israel is not merely a geopolitical actor; it is the axis of a Program that is about to fully manifest itself before the world,”** consolidating a reading that combines political analysis with long-term projection.
|
|
||||||
|
|
||||||
Seventy-six years after its founding, the State of Israel continues to occupy a central place on the global agenda, not only because of its conflicts, but also because of its ability to influence—directly or indirectly—the shape of the international scene.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'International Call for Israel and Venezuela: Faith, Freedom, and Warnings of a Global Shift'
|
|
||||||
date: 2024-08-03
|
|
||||||
slug: 2024-08-03-el-llamado-internacional-por-israel-y-venezuela-fe-libertad-y-advertencias-sobre-un-cambio-global
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-08_14-49-46.jpg'
|
|
||||||
tags: [Venezuela, Puerto Rico]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-08_14-49-46.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# International Call for Israel and Venezuela: Faith, Freedom, and Warnings of a Global Shift
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – August 3, 2024*
|
|
||||||
|
|
||||||
In a global context marked by ongoing sociopolitical conflicts, **Dr. José Benjamín Pérez Matos** issued a statement linking the spiritual dimension with the current geopolitical reality, calling for prayer for two nations in crisis: Israel and Venezuela.
|
|
||||||
|
|
||||||
The message, marked by a sense of urgency, emphasized the need to restore order and stability in key regions, highlighting the impact these developments have on fundamental rights and the well-being of their populations:
|
|
||||||
|
|
||||||
**“May God bless Israel, may God also bless Venezuela, which are the countries currently going through difficult situations; and the other countries as well, because one way or another the kingdoms of this world will soon become the Kingdoms of the Messiah.”**
|
|
||||||
|
|
||||||
One of the central topics of the message focused on the situation in Venezuela, where **Dr. José Benjamín Pérez Matos** referred to the prolonged suffering of the people and the need for a structural change that would make it possible to restore freedom and dignity:
|
|
||||||
|
|
||||||
**“The cry of the children of God is that they may be free from that condition which has been oppressing them for so many years.”**
|
|
||||||
|
|
||||||
The statement also incorporated a broader perspective on the conflicts in the Middle East, interpreting current events as part of a transformation process of greater scope. Within this framework, the “difficult situations” affecting different nations were presented as signs of a transition toward a new order.
|
|
||||||
|
|
||||||
The event concluded with a blessing extended to other countries and a call to maintain an attitude of vigilance and prayer in the face of the ongoing changes, within an international landscape that continues to evolve rapidly and with great complexity.
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Global Warning from Puerto Rico: Israel in a State of Emergency and a Renewed Call for Freedom in Venezuela'
|
|
||||||
date: 2024-08-25
|
|
||||||
slug: 2024-08-25-advertencia-global-desde-puerto-rico-israel-en-emergencia-y-renovado-llamado-por-la-libertad-de-venezuela
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-05_12-41-22.jpg'
|
|
||||||
tags: [Venezuela, 'Puerto Rico']
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-05_12-41-22.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
# Global Warning from Puerto Rico: Israel in a State of Emergency and a Renewed Call for Freedom in Venezuela
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – August 25, 2024*
|
|
||||||
|
|
||||||
At a large-scale conference with international reach via satellite broadcast, **Dr. José Benjamín Pérez Matos** delivered a message with strong geopolitical and spiritual content, focused on the critical situation in the Middle East and the ongoing crisis in Venezuela.
|
|
||||||
|
|
||||||
Before thousands of attendees, **Dr. José Benjamín Pérez Matos** addressed the 48-hour state of emergency declared in Israel following the launch of hundreds of rockets from Lebanon, an episode that heightened tensions in the region and set off alarms internationally. In his remarks, he placed these events within a broader interpretive framework:
|
|
||||||
|
|
||||||
**“For Israel, there will be a very, very great promise that is crystallizing”**.
|
|
||||||
|
|
||||||
Far from limiting himself to a reading of crisis, the message emphasized a perspective of an unfolding process, pointing to a scenario of transformation that reaches beyond the immediate events. In that sense, **Dr. José Benjamín Pérez Matos** noted that the current events should be viewed as part of a “global awakening” tied to the future course of Israel.
|
|
||||||
|
|
||||||
The address also gave central attention to the situation in Venezuela, where the leader made a public appeal for the nation’s freedom, citing the conditions impacting its population:
|
|
||||||
|
|
||||||
**“May God hear the cry of His children”**.
|
|
||||||
|
|
||||||
The message reinforced the idea that the Venezuelan situation represents a critical point within the regional landscape, highlighting the need for change that would restore conditions of freedom and dignity for its people.
|
|
||||||
|
|
||||||
In the last part of the conference, **Dr. José Benjamín Pérez Matos** broadened his message to Latin America, calling for unity and preparation in the face of what he called a period of transition. In this context, he emphasized that, beyond the difficulties expected ahead, faith and prayer serve as key elements for meeting the challenges to come.
|
|
||||||
|
|
||||||
This address reaffirms a consistent line of analysis, one that combines a reading of international events with a long-term perspective, set against a global backdrop marked by increasing complexity and uncertainty.
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'The “Biggest Mistake” in the Middle East: Dr. José Benjamín Pérez Matos Warns of the Impact of International Pressure Against Israel'
|
|
||||||
date: 2024-10-08
|
|
||||||
slug: 2024-10-08-the-biggest-mistake-in-the-middle-east-dr-jose-benjamin-perez-matos-warns-of-the-impact-of-international-pressure-against-israel
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-08_15-19-30.jpg'
|
|
||||||
tags: [Israel, Puerto Rico, Iran]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-08_15-19-30.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# The “Biggest Mistake” in the Middle East: Dr. José Benjamín Pérez Matos Warns of the Impact of International Pressure Against Israel
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – October 8, 2024*
|
|
||||||
|
|
||||||
_From Puerto Rico, the leader of the Kingdom of Peace and Justice Center analyzed the military and geopolitical situation following the escalation of attacks against the State of Israel._
|
|
||||||
|
|
||||||
Against the backdrop of escalating conflict in the Middle East, Dr. José Benjamín Pérez Matos presented an analysis of the security situation facing the State of Israel, focusing on the multiple active fronts and the strategic implications for the nations involved.
|
|
||||||
|
|
||||||
During his remarks, the president of the Kingdom of Peace and Justice Center described the regional environment as a situation of simultaneous pressure on Israel, highlighting the involvement of various state and non-state parties. In that regard, he noted: **“And we also see Israel under attack on all fronts: from the south, the north, in Lebanon, from the… now that country Iran,”** alluding to the complexity of the regional threat landscape.
|
|
||||||
|
|
||||||
Dr. José Benjamín Pérez Matos also emphasized the territorial and strategic asymmetry between Israel and some of its adversaries, arguing that this disparity shapes the course of the conflict. On that point, he stated: **“Just imagine, if you look, Israel is a tiny little strip of land. They are bullies! Humanly speaking, a country as big as Iran is attacking a tiny strip of land, practically driving them out, cornering them to the sea; and they launch, how many bombs? Two hundred-something bombs… and they don’t realize they’re provoking the God of Israel.”**
|
|
||||||
|
|
||||||
The Puerto Rican leader’s statement included a warning to governments and figures who take a stance against Israel, noting that such decisions could have major consequences. In his words: **“Messing with Israel is the biggest mistake a nation can make at this time, as a nation. And messing with the heavenly Israel... is the biggest mistake a person at this time —minister, group, individual people—, it’s the biggest mistake they are making!”**
|
|
||||||
|
|
||||||
He further emphasized that the continuation of military actions against Israel could lead to extremely serious outcomes. In this regard, he said: **“They can keep doing what they are doing; like the nations: bombing, hurting Israel. What is in store for them is terrible!”**
|
|
||||||
|
|
||||||
At the conclusion of his remarks, he included a message of support for the Israeli people, in which he reaffirmed his stance on the conflict and the international situation. In that regard, he stated: **“We pray for Israel; may God keep and watch over them,”** emphasizing the importance of protection amid rising tensions.
|
|
||||||
|
|
||||||
Dr. José Benjamín Pérez Matos’s remarks serve as a warning about the impact of political and military decisions on the international landscape, emphasizing that the stance taken by States toward Israel is a determining factor in the conflict’s evolution.
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'In Jerusalem: Visit to Yesod HaTorah Yeshiva and a Message about the Future of Israel as a Global Center'
|
|
||||||
date: 2024-12-17
|
|
||||||
slug: 2024-12-17-in-jerusalem-visit-to-yesod-hatorah-yeshiva-and-a-message-about-the-future-of-israel-as-a-global-center
|
|
||||||
place: ''
|
|
||||||
country: 'IL'
|
|
||||||
city: Jerusalem
|
|
||||||
tags: [Israel]
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# In Jerusalem: Visit to Yesod HaTorah Yeshiva and a Message about the Future of Israel as a Global Center
|
|
||||||
|
|
||||||
*Jerusalem, Israel – December 17, 2024*
|
|
||||||
|
|
||||||
During a recent visit to Israel, Dr. José Benjamín Pérez Matos visited Yesod HaTorah Yeshiva, in Jerusalem, where he was welcomed in a setting of scholarly tradition dedicated to the teaching of the Torah and the Talmud. The meeting, held in a relevant academic-religious environment, was underscored by a message centered on the value of spiritual knowledge and its global reach.
|
|
||||||
|
|
||||||
Upon speaking, Dr. José Benjamín Pérez Matos emphasized the importance of an education grounded in sacred texts to build a society with a solid foundation, conveying a vision about the future of Israel in the global landscape:
|
|
||||||
|
|
||||||
> **“It’s a blessing and an honor to be here in the yeshivah of my friend Moshe, and to see the different classrooms where the Torah and Talmud are studied. Continue holding onto the Torah, to the Word of God. And may the Eternal One continue giving you plenty of wisdom and understanding. And may you soon see the establishment of that long awaited Kingdom: the Kingdom of peace, of happiness and prosperity, that Israel longs for. Which is very near.**
|
|
||||||
>
|
|
||||||
> **And Israel will be the capital of the entire world. And you are part of that Kingdom; it will be established soon.”**
|
|
||||||
|
|
||||||
The visit unfolded amid growing interest in the role of religious institutions in shaping visions for the future, particularly in terms of the relationship between tradition, leadership, and global transformation.
|
|
||||||
|
|
||||||
In this regard, the message from Jerusalem strengthens a perspective that connects Torah study to a horizon of geopolitical and spiritual change, placing Israel at the heart of the construction of an international landscape geared toward peace, stability, and prosperity.
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Faith Diplomacy and Geopolitical Power: The Latin America–Israel Axis at the Center of the New International Landscape'
|
|
||||||
date: 2024-12-17
|
|
||||||
slug: 2024-12-17-faith-diplomacy-and-geopolitical-power-the-latin-america–israel-axis-at-the-center-of-the-new-international-landscape
|
|
||||||
place: ''
|
|
||||||
country: 'IL'
|
|
||||||
city: 'Jerusalem'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
|
|
||||||
tags: [Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Faith Diplomacy and Geopolitical Power: The Latin America–Israel Axis at the Center of the New International Landscape
|
|
||||||
|
|
||||||
*Jerusalem, Israel – December 17, 2024*
|
|
||||||
|
|
||||||
The recent tour of the Middle East, along with statements issued from Puerto Rico and Mexico by Dr. José Benjamín Pérez Matos, have brought light to the consolidation of a political-religious actor with growing international projection. His speech, which weaves together faith, strategy, and geopolitical positioning, seeks to directly influence the conflict in Gaza and the legitimacy of the State of Israel within the international system.
|
|
||||||
|
|
||||||
One of the most notable aspects of this approach has been the message’s shift in tone: from a framework centered exclusively on prayer to a stance that demands decisive action in the international political stage. In this regard, the need for an “uprising against terrorism” in Gaza has been proposed, accompanied by criticism of the lack of resolve among multilateral organizations and governments that have scaled back on their support for Israel. The stance is clear: the formation of a Palestinian state is not considered viable under the current conditions, but only within a framework subordinate to the laws and conditions of the Israeli State.
|
|
||||||
|
|
||||||
At the same time, a novel strategic line emerges centered on the use of resources as a negotiation tool. In particular, the water crisis in Iran is presented as an opportunity for diplomacy grounded on concrete solutions. From this perspective, Israel is not only positioned as a military power, but also as a provider of key technology for regional survival, shaping a logic of “peace for resources” that redefines traditional mechanisms of negotiation.
|
|
||||||
|
|
||||||
Another central point of the analysis lies in the recognition achieved within the highest religious and political spheres of Jerusalem. Meetings with Israeli Government officials and with Chief Rabbi Kalman Ber transcend beyond the symbolic or ecclesiastical realm, projecting themselves as signals of mutual legitimacy. The establishment of a “brotherhood” relationship with the Ashkenazi Chief Rabbi suggests the formation of a bloc of influence with aspirations to play a role in potential global reordering.
|
|
||||||
|
|
||||||
In this context, Latin America and the Caribbean emerge as a rising actor within this framework. According to these statements, a regional front is taking shape that serves as a counterweight to countries maintaining critical positions against Israel. This bloc not only offers political and moral support, but also projects itself as a strategic ally in the defense of Israeli sovereignty, expanding the geopolitical reach of the region.
|
|
||||||
|
|
||||||
His analysis concluded with a clear message: this is a strategy that departs from traditional diplomacy frameworks, leaning towards an approach of structural strength. The viability of the two-State solution in the current context is in question, and the emergence of a new international hierarchy is proposed, in which Israel would occupy a central role, integrating political and religious dimensions within a single axis of power.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Return From Israel With Historic Results: A Mission Marked by Symbolism and Diplomatic Achievements'
|
|
||||||
date: 2024-12-19
|
|
||||||
slug: 2024-12-19-faith-diplomacy-and-geopolitical-power-the-latin-america–israel-axis-at-the-center-of-the-new-international-landscape
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-08_18-21-03.jpg'
|
|
||||||
tags: [Puerto Rico, Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-08_18-21-03.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Return From Israel With Historic Results: A Mission Marked by Symbolism and Diplomatic Achievements
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – December 19, 2024*
|
|
||||||
|
|
||||||
After an intense international tour that included Africa and the Middle East, Dr. José Benjamín Pérez Matos returned to Puerto Rico highlighting the historic significance of the results achieved during his recent visit to Israel. The trip, shaped by the context of conflict in the region, was marked both by logistical challenges and by a series of events that, as expressed, acquired significant symbolic and diplomatic value.
|
|
||||||
|
|
||||||
One of the most relevant aspects of the mission was changing the entry route into Israel. Due to the cancellation of commercial flights to Tel Aviv, the delegation had to reorganize its itinerary, traveling first to Dubai, United Arab Emirates, and then entering Israeli territory from the east. This change, initially technical, was interpreted as an event of profound significance:
|
|
||||||
|
|
||||||
The so‑called “entry from the east” was associated by Dr. José Benjamín Pérez Matos with a symbolic reference linked to the “rising of the sun,” adding an additional dimension to the experience that went beyond the purely operational.
|
|
||||||
|
|
||||||
Despite the short duration of the visit, the work agenda included high‑level meetings that, according to reports, generated a positive assessment from local interlocutors. In various spheres—both religious and political—the intensity and effectiveness of the meetings held within a short period were highlighted.
|
|
||||||
|
|
||||||
In that regard, Dr. José Benjamín Pérez Matos himself emphasized the significance of the results obtained:
|
|
||||||
|
|
||||||
**“In just a few days, we accomplished things that even those in Israel themselves said were impossible to achieve in such a short time.”**
|
|
||||||
|
|
||||||
The mission’s assessment reflects an approach aimed at maximizing opportunities in complex contexts, strengthening ties in scenarios of high international sensitivity. The return to Puerto Rico thus marks the closing of a stage that, as noted, could have relevant implications for future institutional and diplomatic developments.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Jerusalem in the Spotlight in 2025: Warnings About a Pivotal Year for Global Change'
|
|
||||||
date: 2025-01-04
|
|
||||||
slug: 2025-01-04-jerusalem-in-the-spotlight-in-2025-warnings-about-a-pivotal-year-for-global-change
|
|
||||||
place: ''
|
|
||||||
country: 'PR'
|
|
||||||
city: 'Cayey'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/7K0B4402.webp?tr=w-1280,q-auto,f-auto'
|
|
||||||
tags: [Puerto Rico, Israel]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/7K0B4402.webp?tr=w-1280,q-auto,f-auto',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Jerusalem in the Spotlight in 2025: Warnings About a Pivotal Year for Global Change
|
|
||||||
|
|
||||||
*Cayey, Puerto Rico – January 4, 2025*
|
|
||||||
|
|
||||||
In an international setting marked by uncertainty and the shifting of global balances, recent statements by Dr. José Benjamín Pérez Matos, once again position Jerusalem as a key point in the unfolding of world events. According to his vision, the year 2025 is shaping up to be a decisive period in which transformation processes of global scope will accelerate.
|
|
||||||
|
|
||||||
The approach is not limited to a conventional geopolitical interpretation; rather, it combines a spiritual dimension with an analysis of the international reality, positioning the Holy City not only as a historical reference point, but also as a driving force behind ongoing structural change.
|
|
||||||
|
|
||||||
One of the key points of the message lies in the relationship with Israel. In this regard, Dr. José Benjamín Pérez Matos spoke of a direct and lasting connection with the Jewish people, highlighting the emotional and spiritual bond that unites his community with the fate of the Israeli nation, which he **“loves and carries in his heart.”**
|
|
||||||
|
|
||||||
This brief yet meaningful statement encapsulates a vision that transcends the symbolic realm and extends into the future. Within this framework, Israel’s role appears linked to the possibility of establishing itself as the center of a global order oriented toward peace and justice.
|
|
||||||
|
|
||||||
The message also introduces a specific temporal dimension. The repeated reference to the year 2025 as a turning point suggests an expectation of high-impact events that will shape the direction of ongoing processes. Accordingly, Dr. José Benjamín Pérez Matos noted that this is a period in which multiple developments will begin to materialize, consolidating a phase of decisive outcomes.
|
|
||||||
|
|
||||||
The mention of events carried out both in Puerto Rico and in Jerusalem reinforces the idea that this process is already underway, inviting those who follow this message to maintain a posture of attentiveness, preparedness, and expectation.
|
|
||||||
|
|
||||||
In a global context where political tensions, social transformations, and structural challenges converge, the centrality of Jerusalem emerges in this analysis as a key element for understanding the potential configuration of the international landscape in the coming years.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'From Mexico: Dr. José Benjamín Pérez Matos Reaffirms His Global Commitment to Israel and its Projection in 2025'
|
|
||||||
date: 2025-01-13
|
|
||||||
slug: 2025-01-13-from-mexico-dr-jose-benjamin-perez-matos-reaffirms-his-global-commitment-to-israel-and-its-projection-in-2025
|
|
||||||
place: ''
|
|
||||||
country: 'MX'
|
|
||||||
city: 'Mexico City'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-05_12-41-41.jpg'
|
|
||||||
tags: [Mexico]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-05_12-41-41.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# From Mexico: Dr. José Benjamín Pérez Matos Reaffirms His Global Commitment to Israel and its Projection in 2025
|
|
||||||
|
|
||||||
*Mexico City, Mexico – January 13, 2025*
|
|
||||||
|
|
||||||
With a large-scale event at Mexico City’s Plaza de Toros fast approaching, Dr. José Benjamín Pérez Matos toured the facilities to oversee the preparations alongside the coordinating team.
|
|
||||||
|
|
||||||
In light of the event, which has generated international interest, he delivered an inclusive message focused on the relationship between Latin America and Israel, highlighting a period of greater visibility and strengthening of the ties between the two regions.
|
|
||||||
|
|
||||||
During his remarks, Dr. José Benjamín Pérez Matos emphasized that the connection with the Hebrew people will not only be maintained, but will deepen over time, taking on an increasingly prominent role on the international scene:
|
|
||||||
|
|
||||||
**“We love Israel and stand with Israel in everything; and that connection with the Hebrew people will become increasingly evident.”**
|
|
||||||
|
|
||||||
The message also included a direct reference to Latin America’s role in this process, proposing a regional identity aligned with support for Israel and outlining a strategy with global reach. In this regard, Dr. José Benjamín Pérez Matos defined his personal stance and upcoming course of action:
|
|
||||||
|
|
||||||
**“All of the Latin American people love Israel. And wherever I go, I will speak about Israel as well; because that is where God will rule the entire world from; and I will be an ambassador and I am an ambassador for the people of Israel throughout the world.”**
|
|
||||||
|
|
||||||
The statements outline a clear agenda for 2025, in which Israel plays a central role in both Dr. José Benjamín Pérez Matos’s lecture as well as his international efforts. The emphasis on spreading this message globally reinforces a strategy aimed at building support and positioning the relationship between Latin America and Israel as a key pillar on the global stage.
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
---
|
|
||||||
locale: en
|
|
||||||
title: 'Liberation in Israel: A Day of Faith, Gratitude, and a Call for Freedom'
|
|
||||||
date: 2025-01-19
|
|
||||||
slug: 2025-01-19-liberation-in-israel-a-day-of-faith-gratitude-and-a-call-for-freedom
|
|
||||||
place: ''
|
|
||||||
country: 'US'
|
|
||||||
state: 'Illinois'
|
|
||||||
city: 'Chicago'
|
|
||||||
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-05-05_12-41-37.jpg'
|
|
||||||
tags: [United States, Venezuela]
|
|
||||||
gallery: [
|
|
||||||
{
|
|
||||||
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-05-05_12-41-37.jpg',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Liberation in Israel: A Day of Faith, Gratitude, and a Call for Freedom
|
|
||||||
|
|
||||||
*Chicago, Illinois, United States – January 19, 2025*
|
|
||||||
|
|
||||||
A day marked by hope, the release of the first three female hostages in Israel made an impact across the geopolitical sphere, awakening a deep emotional and spiritual response in communities that have closely followed the development of the conflict.
|
|
||||||
|
|
||||||
The confirmation that the first women released were in the hands of the Red Cross was received with relief and gratitude. In this context, Dr. José Benjamín Pérez Matos expressed the sentiment of those who have accompanied these events through prayer and constant monitoring:
|
|
||||||
|
|
||||||
**“We feel the joy of the families, and we feel it as if they were our own families.”**
|
|
||||||
|
|
||||||
Beyond the diplomatic and operational aspects, the message emphasized the spiritual dimension of the process. As he expressed, their release was a response to a long-standing plea:
|
|
||||||
|
|
||||||
**“The God of Israel, who is also our God, has answered our prayers in favor of the hostages. The agreed upon phase of their release begins today, and we thank the Eternal One for hearing our cry.”**
|
|
||||||
|
|
||||||
Dr. José Benjamín Pérez Matos reaffirmed his commitment to ongoing support for the people of Israel, highlighting the emotional bond with the impacted families and the hope that the rest of the hostages return under similar condition:
|
|
||||||
|
|
||||||
**“We feel the joy of the families, and we also rejoice that these women are free and alive. We hope that the others [who are still held hostage] are also alive.”**
|
|
||||||
|
|
||||||
Later that day, he recalled previous statements that reflect the enduring call for the hostages’ release. In this regard, Dr. José Benjamín Pérez Matos recalled his words addressed to a Knesset member: **“May they be released!”**
|
|
||||||
|
|
||||||
The message was not limited to the Middle East. In a shift towards Latin America, Dr. José Benjamín Pérez Matos connected his appeal to the situation in Venezuela, incorporating a regional dimension into the statement:
|
|
||||||
|
|
||||||
**“Pray for Venezuela as well, for that people whom we love and wish to see liberated as well. We declare freedom for Venezuela!”**
|
|
||||||
|
|
||||||
Finally, he emphasized the need for a firm response from the international community:
|
|
||||||
|
|
||||||
**“May God work and governments move; may it not be just a facade, but real action: may they move in favor of Venezuela, and may the Venezuelan people be set free!”**
|
|
||||||
|
|
||||||
The day concluded with a vision of unity that integrates faith, solidarity, and action, linking in a single horizon the peace in Israel and the appreciation for freedom in other regions of the world. His message reaffirmed a continuous line of support, where the spiritual dimension and the analysis of international events converge into a single narrative.
|
|
||||||