From 934aed1d5214c8aea301009f15436875a9830db9 Mon Sep 17 00:00:00 2001 From: David Itehua Xalamihua Date: Sun, 18 May 2025 17:33:54 -0600 Subject: [PATCH] cambio en footer, soluciones y carousel --- README.md | 30 +- .../cls_form_carousel.cpython-312.pyc | Bin 1384 -> 1374 bytes forms_py/cls_form_carousel.py | 2 +- main.py | 37 +- static/a_home/home.css | 13 + static/c_solutions/solutions.css | 2 +- static/d_methodology/methodology.css | 20 +- .../i_carousel_form/carousel_form.js | 6 + .../i_carousel_form/datatable_carousel.js | 99 ++++ .../i_carousel_form/delete_slide.js | 80 +++ static/template/navbar_footer.css | 9 +- static/y_img/methodology/m-01.svg | 219 ++++++++ static/y_img/methodology/m-02.svg | 228 ++++++++ templates/a_home/home.html | 2 + templates/d_methodology/methodology.html | 68 +-- templates/h_tmp_usr/c_my_posts.html | 80 ++- templates/h_tmp_usr/i_carousel_form.html | 509 ++++++++++++------ templates/z_comps/footer.html | 87 +-- 18 files changed, 1198 insertions(+), 293 deletions(-) create mode 100644 static/h_tmp_user/i_carousel_form/datatable_carousel.js create mode 100644 static/h_tmp_user/i_carousel_form/delete_slide.js create mode 100644 static/y_img/methodology/m-01.svg create mode 100644 static/y_img/methodology/m-02.svg diff --git a/README.md b/README.md index f2f0f94..643f678 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Descargar y mover el repositorio +## Descargar y mover el repositorio ```bash cd ~ git clone gitea@192.168.10.40:dix/formha.git @@ -6,12 +6,12 @@ sudo mv formha/ /var/www cd /var/www/formha/ ``` -# Entrar en modo Dios +## Entrar en modo Dios ```bash sudo su ``` -# Crear el ambiente virtual +## Crear el ambiente virtual ```bash python3 -m venv .venv source .venv/bin/activate @@ -19,13 +19,13 @@ pip install -r requirements.txt deactivate ``` -# Salimos del modo Dios +## Salimos del modo Dios ```bash exit ``` -# Añade las variables de entorno del proyecto al archivo envars - - si tienes problemas con las variables de entorno deberás de comentarlas y reiniciar apache, una vez reiniciado deberas descomentar las variables de entorno y volver a reiniciar apache +## Añade las variables de entorno del proyecto al archivo **envars** + Sí tienes problemas con las variables de entorno deberás de comentarlas y reiniciar apache, una vez reiniciado deberás descomentar las variables de entorno y volver a reiniciar apache ```bash sudo nano /etc/apache2/envvars ``` @@ -46,19 +46,27 @@ export forma_db='{ #///////////////////////////////////// ``` -# Movemos el archivo de configuración a Apache (solo se hace 1 vez) -## SI TE DA ERROR PRIMERO DESACTIVA APACHE EL PROBLEMA ES LAS VARIABLES DE ENTORNO - sudo systemctl stop apache2 +## Movemos el archivo de configuración a Apache (solo se hace 1 vez) +### SI TE DA ERROR PRIMERO DESACTIVA APACHE EL PROBLEMA ES LAS VARIABLES DE ENTORNO + +```bash +sudo systemctl stop apache2 sudo mv formha.conf /etc/apache2/sites-available/ cd /etc/apache2/sites-available/ sudo a2ensite formha.conf - +``` +## Reiniciar apache ```bash sudo systemctl reload apache2 sudo systemctl restart apache2 ``` +# IMPORTANTE +- Debes de dar permisos a la ruta de archivos UPLOAD (solo se ejecuta una vez) +```bash +sudo chown -R www-data:www-data /var/www/uploads/formha +sudo chmod -R 755 /var/www/uploads/formha +``` - diff --git a/forms_py/__pycache__/cls_form_carousel.cpython-312.pyc b/forms_py/__pycache__/cls_form_carousel.cpython-312.pyc index 4e9f4090c43db8a406268679578749e4a55c4d22..e8f9781757adc95cbebb33508f69101fa8ab2019 100644 GIT binary patch delta 65 zcmaFCb&repG%qg~0}!ZMYh^TS=v08=!hpzg-3%{dnX UVlD^7UGR^;!k@5NhsA~w0E@*HnE(I) delta 75 zcmcb|^@5A{G%qg~0}%9Gl*{Pa$UB=!LdrQmC%;G`B~>9UKQAR8$jDJBNv$Z^yp1WE dQPBJ#*I}NEQE8W>GA=}BUg6K$ti)o&2mqy28Sel9 diff --git a/forms_py/cls_form_carousel.py b/forms_py/cls_form_carousel.py index f715361..747532b 100644 --- a/forms_py/cls_form_carousel.py +++ b/forms_py/cls_form_carousel.py @@ -54,7 +54,7 @@ class Carousel(FlaskForm): ] ) - bg_color = StringField('Color de fondo del texto: ', widget=ColorInput(), validators=[DataRequired()]) + bg_color = StringField('Color de fondo: ', widget=ColorInput(), validators=[DataRequired()]) txt_color = StringField('Color del texto: ', widget=ColorInput(), validators=[DataRequired()]) diff --git a/main.py b/main.py index ad08105..0909de1 100644 --- a/main.py +++ b/main.py @@ -33,7 +33,7 @@ if 'microsoft' in platform.uname().release.lower(): folder_upload = os.path.join(os.getcwd(), "static", "uploads") elif platform.system() == "Linux": - folder_upload = "/var/www/formha/static/uploads/" + folder_upload = "/var/www/uploads/formha" @@ -183,7 +183,7 @@ def solutions(): return render_template(v['solutions'], active_page='solutions') @app.route('/methodology') -@cache.cached(timeout=43200) +# @cache.cached(timeout=43200) def methodology(): return render_template(v['methodology'], active_page='methodology') @@ -419,13 +419,32 @@ def recover_pswd(): recipients=[emailPswdReco] # Asegúrate que es una lista ) - # msg.html = render_template( 'email/recover_pswd.html', temp_password=new_tmp_pswd ) - - msg.html = """ -

Nueva contraseña temporal:

-

Contraseña: {}

-

Una vez iniciada tu sesión debes de cambiar la contraseña a una nueva que puedas recordar

- """.format(new_tmp_pswd) + + msg.html = f""" + + + + + Recuperación de contraseña + + +
+

🔒 Recuperación de contraseña

+

Hola,

+

Hemos recibido una solicitud para restablecer tu contraseña. A continuación te proporcionamos una contraseña temporal que podrás usar para iniciar sesión:

+ +

🔑 Contraseña temporal: {new_tmp_pswd}

+ +

Importante: Una vez que inicies sesión, te recomendamos cambiar tu contraseña por una que solo tú conozcas y puedas recordar fácilmente.

+ +
+

Este es un mensaje automático, por favor no respondas a este correo.

+
+ + + """ + + dbUsers.update_pswd(pswd=hashed_new_pswd, email=emailPswdReco) diff --git a/static/a_home/home.css b/static/a_home/home.css index a8a696c..54fbeb4 100644 --- a/static/a_home/home.css +++ b/static/a_home/home.css @@ -55,6 +55,7 @@ height: 100vh; object-fit: cover; } + main { min-height: 80dvh; } } /* --------- Responsivo (ajustes si necesitas) ---------- */ @@ -68,6 +69,8 @@ .carousel-caption.centered .caption-content h2 { font-size: 1.5rem; } + + main { min-height: 80dvh; } } /* Tablets */ @@ -75,14 +78,24 @@ .carousel-caption.centered .caption-content h2 { font-size: 2rem; } + main { min-height: 80dvh; } } /* Laptops */ @media (min-width: 1024px) and (max-width: 1439px) { /* ajustes opcionales */ + main { min-height: 80dvh; } } /* Pantallas grandes */ @media (min-width: 1440px) { /* ajustes opcionales */ + main { min-height: 80dvh; } } + + + + + + + diff --git a/static/c_solutions/solutions.css b/static/c_solutions/solutions.css index 13d9803..043cf6a 100644 --- a/static/c_solutions/solutions.css +++ b/static/c_solutions/solutions.css @@ -163,7 +163,7 @@ main { main { background-size: 50% auto; /* 30% del ancho del contenedor */ - height: 80vh; + min-height: 70dvh; } } diff --git a/static/d_methodology/methodology.css b/static/d_methodology/methodology.css index 17eb681..c626bff 100644 --- a/static/d_methodology/methodology.css +++ b/static/d_methodology/methodology.css @@ -1,13 +1,21 @@ -.container{ - & p { - font-size: 1.5rem; - } -} - main { place-items: center; } +#random-img { + width: 70%; + height: auto; + + background-color: #fff; + border-radius: 12px; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); + padding: 1rem; +} + + + + + /* Smartphones (hasta 767px) */ @media (max-width: 767px) { /* main{ background-color: black; } */ diff --git a/static/h_tmp_user/i_carousel_form/carousel_form.js b/static/h_tmp_user/i_carousel_form/carousel_form.js index 7866bb6..4d30f42 100644 --- a/static/h_tmp_user/i_carousel_form/carousel_form.js +++ b/static/h_tmp_user/i_carousel_form/carousel_form.js @@ -1,6 +1,12 @@ import { simpleNotification } from '../../z_comps/notify.js'; +// valida los archivos que se cargan en el formulario +// solo permite jpg, jpeg, png, mp4 +// y los archivos que no son de imagen se eliminan +// y se muestra un mensaje de error + + let form = document.querySelector("form"); let img = document.getElementById("img"); diff --git a/static/h_tmp_user/i_carousel_form/datatable_carousel.js b/static/h_tmp_user/i_carousel_form/datatable_carousel.js new file mode 100644 index 0000000..eba9ac3 --- /dev/null +++ b/static/h_tmp_user/i_carousel_form/datatable_carousel.js @@ -0,0 +1,99 @@ +new DataTable('#tblCarousel', { + responsive: { + details: { + type: 'column', + renderer: function (api, rowIdx, columns) { + const data = $.map(columns, function (col) { + // Excluir columnas ocultas con títulos no deseados + if ( + col.hidden && + !( + col.title.includes("ID") || + col.title === 'Acciones' + ) + ) { + return ` + + ${col.title}: + ${col.data} + + `; + } + return ''; + }).join(''); + + return data + ? $('').append(`${data}`) + : false; + } + } + }, + + autoWidth: false, + dom: '<"top"lf>rt<"bottom"ip>', + + language: { + search: "Buscar:", + lengthMenu: "Mostrar _MENU_ registros", + info: "Mostrando _START_ a _END_ de _TOTAL_ registros", + infoEmpty: "Mostrando 0 a 0 de 0 registros", + infoFiltered: "(filtrado de _MAX_ registros totales)", + paginate: { + first: "Primero", + last: "Último", + next: "Siguiente", + previous: "Anterior" + } + }, + + initComplete: function () { + const api = this.api(); + + // Agregar filtros a columnas que lo permiten + api.columns().every(function () { + const column = this; + const header = $(column.header()); + const title = header.text().trim(); + + + + if ( + !( + title.includes("ID") || + title === 'New Tab' || + title === 'Acciones' + ) + ) { + const input = $('') + .appendTo(header.empty()) // Vaciar el th antes de agregar input + .on('keyup change', function () { + if (column.search() !== this.value) { + column.search(this.value).draw(); + } + }); + + input.css('width', '100%'); + } + }); + + // Ajustes al redimensionar ventana + $(window).on('resize', function () { + $('.dataTables_scrollHeadInner, .dataTables_scrollHeadInner table').css('width', '100%'); + }); + }, + + drawCallback: function () { + // Asegurar ancho correcto si hay columnas ocultas + if (this.api().responsive.hasHidden()) { + $('.dataTables_scrollHeadInner, .dataTables_scrollHeadInner table').css('width', '100%'); + } + }, + + columnDefs: [ + { responsivePriority: 1, targets: 0 }, // ID + { responsivePriority: 2, targets: -1 }, // Acciones + { responsivePriority: 3, targets: 2 }, // Archivo + { width: '80px', targets: 0 }, // Ancho para ID + { width: '120px', targets: -1 } // Ancho para Acciones + ] +}); diff --git a/static/h_tmp_user/i_carousel_form/delete_slide.js b/static/h_tmp_user/i_carousel_form/delete_slide.js new file mode 100644 index 0000000..b38d6c0 --- /dev/null +++ b/static/h_tmp_user/i_carousel_form/delete_slide.js @@ -0,0 +1,80 @@ +import { simpleNotification } from '../../z_comps/notify.js'; + + +function delete_file(e) { + let btn = $(this); + let postId = btn.data('id'); + let url = `${window.location.origin}/user/carousel/delete-slide/${postId}`; + + fetch(url, { + method: 'DELETE', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('token_ai') // o tu token JWT + } + }) + .then(res => res.json()) + .then(data => { + if (data.msg) { + console.log(data.msg); + let btn = document.querySelector(`[data-id="${postId}"]`); + let row = $(btn).closest('tr'); // usa jQuery para compatibilidad con DataTables + let table = $('#tblCarousel').DataTable(); // obtiene instancia + + table.row(row).remove().draw(); // elimina la fila y redibuja la tabla + + simpleNotification("Eliminación exitosa", `${data.msg}`, "success"); + + // eliminar el tr del slide si quieres: btn.closest('tr').remove(); + } else { + console.error('Error:', data.error); + } + }) + .catch(err => console.error('Error en fetch:', err)); + } + + + + + // https://htmlguyllc.github.io/jConfirm/ + $(function(){ + $('.delete-btn').jConfirm({ + //false|array: if provided, this will override the default confirm/deny buttons (see below for an example) + btns: false, + //string: question displayed to the user + question: '¿Deseas continuar con la eliminación?', + //string: confirm button text + confirm_text: 'Sí', + //string: deny button text + deny_text: 'No', + //boolean: if true, when the confirm button is clicked the user will be redirected to the button's href location + // follow_href: true, + //boolean: if true and follow_href is true, the href will be opened in a new window + open_new_tab: false, + //boolean: if true, the tooltip will be hidden if you click outside of it + hide_on_click: true, + //string ('auto','top','bottom','left','right'): preferred location of the tooltip (defaults to auto if no space) + position: 'auto', + //boolean: if true, the deny button will be shown + show_deny_btn: true, + //string ('black', 'white', 'bootstrap-4', 'bootstrap-4-white') + theme: 'bootstrap-4', + //string ('tiny', 'small', 'medium', 'large') + size: 'medium', + //boolean: show the tooltip immediately on instantiation + show_now: false, + //string: class(es) to add to the tooltip + 'class': '' + }).on('confirm', delete_file) + .on('deny', function(e){ + var btn = $(this); + //do something on deny + }).on('jc-show', function(e, tooltip){ + // console.log("el tooltip es visible"); + //do something when tooltip is shown + //tooltip dom element is passed as the second parameter + + }).on('jc-hide', function(e){ + //do something when tooltip is hidden + }); + + }); \ No newline at end of file diff --git a/static/template/navbar_footer.css b/static/template/navbar_footer.css index 1f9301f..269737d 100644 --- a/static/template/navbar_footer.css +++ b/static/template/navbar_footer.css @@ -94,9 +94,9 @@ /* Estilos personalizados para el footer */ .footer { - background-color: var(--navbar-footer-color); + background-color: var(--navbar-footer-color) !important; font-size: var(--font-size-formha); - color: white; + color: white !important; padding: 3rem 0; & .img-cont{ @@ -104,6 +104,11 @@ background-color: white; border-radius: 10px; } + + & i, a { + color: white !important; + } + } .footer h5 { diff --git a/static/y_img/methodology/m-01.svg b/static/y_img/methodology/m-01.svg new file mode 100644 index 0000000..eb341f0 --- /dev/null +++ b/static/y_img/methodology/m-01.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + EXPERIENCIA DE SERVICIO + Acompañamos cada paso del proyecto, asegurando una experiencia cercana, ágil y efectiva. + SOSTENIBILIDAD DEL CAMBIO + Reforzamos capacidades internas para que el valor se mantenga a largo plazo, más allá del proyecto. + ANÁLISIS DE DATOS + Identificamos información clave para entender las metas, retos y oportunidades de tu empresa. + METODOLOGÍA + Implementamos soluciones con el enfoque humano, técnico y estratégico. + PERSONALIZACIÓN + IMPACTO + + + + 01 + + + + + + + + + + 03 + + + + + + + + + + 05 + + + + + + + + + + 04 + + + + + + + + + + 02 + + + + + + + Diseñamos estrategías a la medida, utilizando metodologías especializadas y herramientas tecnológicas. + Medimos resultados con métricas claras para asegurar que cada intervención tenga efectos tangibles. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/y_img/methodology/m-02.svg b/static/y_img/methodology/m-02.svg new file mode 100644 index 0000000..82dfd78 --- /dev/null +++ b/static/y_img/methodology/m-02.svg @@ -0,0 +1,228 @@ + + + + + + + + + EXPERIENCIA DE SERVICIO + Acompañamos cada paso del proyecto, asegurando una experiencia cercana, ágil y efectiva. + SOSTENIBILIDAD DEL CAMBIO + Reforzamos capacidades internas para que el valor se mantenga a largo plazo, más allá del proyecto. + ANÁLISIS DE DATOS + Identificamos información clave para entender las metas, retos y oportunidades de tu empresa. + METODOLOGÍA + Implementamos soluciones con el enfoque humano, técnico y estratégico. + PERSONALIZACIÓN + IMPACTO + + + + 01 + + + + + + + + + + 03 + + + + + + + + + + 05 + + + + + + + + + + 04 + + + + + + + + + + 02 + + + + + + + Diseñamos estrategías a la medida, utilizando metodologías especializadas y herramientas tecnológicas. + Medimos resultados con métricas claras para asegurar que cada intervención tenga efectos tangibles. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/a_home/home.html b/templates/a_home/home.html index df24298..41f90fa 100644 --- a/templates/a_home/home.html +++ b/templates/a_home/home.html @@ -10,6 +10,8 @@ {% block body %} + +
+
- - - - - - + + + + + + + + {% for ele in data %} @@ -131,77 +335,147 @@ {% endfor %} -
IDCreadoArchivoNew TabTextoAcciones
IDCreadoArchivoNew TabTextoAcciones
-
- -
+

Agregar Slide

- + + + - -
- {{ form.bg_color.label() }} - {{ form.bg_color( type="color", class_="form-control form-control-color", value="") }} -
- -
- {{ form.txt_color.label() }} - {{ form.txt_color( type="color", class_="form-control form-control-color", value="" ) }} -
- -
- {{ form.txt.label() }} - {{ form.txt( class_="form-control" ) }} -
- -
- {{ form.url.label() }} - {{ form.url( class_="form-control" ) }} -
- -
-
- {{ form.isNewTab( class_="form-check-input", type="checkbox" ) }} - {{ form.isNewTab.label() }} -
-
- -
- +
-