diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 0dcdf21..1c198d8 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -14,10 +14,10 @@ jobs: run: | if [ "${{ gitea.ref_name }}" = "production" ]; then echo "TARGET_DIR=/var/www/node/cdrdpyj" >> $GITHUB_ENV - echo "PM2_ENV=production" >> $GITHUB_ENV + echo "APP_NAME=cdrdpyj-live" >> $GITHUB_ENV else - echo "TARGET_DIR=/var/www/node/dev.cdrdjyp" >> $GITHUB_ENV - echo "PM2_ENV=staging" >> $GITHUB_ENV + echo "TARGET_DIR=/var/www/node/dev.cdrdpyj" >> $GITHUB_ENV + echo "APP_NAME=cdrdpyj" >> $GITHUB_ENV fi - uses: pnpm/action-setup@v4 @@ -53,7 +53,7 @@ jobs: npm install -g pnpm@11 2>&1 cd ${{ env.TARGET_DIR }} pnpm install --prod 2>&1 - sed -i "s|TURNSTILE_SITE_KEY: \"\"|TURNSTILE_SITE_KEY: \"${{ secrets.TURNSTILE_SITE_KEY }}\"|" ecosystem.config.cjs - sed -i "s|TURNSTILE_SECRET_KEY: \"\"|TURNSTILE_SECRET_KEY: \"${{ secrets.TURNSTILE_SECRET_KEY }}\"|" ecosystem.config.cjs - pm2 reload ecosystem.config.cjs --env ${{ env.PM2_ENV }} --update-env || \ - pm2 start ecosystem.config.cjs --env ${{ env.PM2_ENV }} --update-env + sed -i "s|TURNSTILE_SITE_KEY: \"\"|TURNSTILE_SITE_KEY: \"${{ secrets.TURNSTILE_SITE_KEY }}\"|g" ecosystem.config.cjs + sed -i "s|TURNSTILE_SECRET_KEY: \"\"|TURNSTILE_SECRET_KEY: \"${{ secrets.TURNSTILE_SECRET_KEY }}\"|g" ecosystem.config.cjs + pm2 reload ecosystem.config.cjs --only ${{ env.APP_NAME }} --update-env || \ + pm2 start ecosystem.config.cjs --only ${{ env.APP_NAME }} --update-env diff --git a/.opencode/skills/dynamic-form/SKILL.md b/.opencode/skills/dynamic-form/SKILL.md new file mode 100644 index 0000000..d46dc71 --- /dev/null +++ b/.opencode/skills/dynamic-form/SKILL.md @@ -0,0 +1,186 @@ +--- +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` | `` inside daisyUI `