mejoramiento de sección blog en vista pública
This commit is contained in:
parent
b661a265ea
commit
8273b48b6b
25
main.py
25
main.py
@ -218,10 +218,11 @@ def blog():
|
|||||||
|
|
||||||
|
|
||||||
@app.route('/blog/<int:post_id>')
|
@app.route('/blog/<int:post_id>')
|
||||||
|
# @cache.cached(timeout=43200)
|
||||||
def blog_post(post_id):
|
def blog_post(post_id):
|
||||||
q_visited = "INSERT INTO posts_visited (id_post, viewed ) VALUES ( %s, %s);"
|
# q_visited = "INSERT INTO posts_visited (id_post, viewed ) VALUES ( %s, %s);"
|
||||||
t_visited = (post_id, cur_date())
|
# t_visited = (post_id, cur_date())
|
||||||
dbUsers.update_data(q_visited, t_visited)
|
# dbUsers.update_data(q_visited, t_visited)
|
||||||
# Obtener el post
|
# Obtener el post
|
||||||
q = fr"""
|
q = fr"""
|
||||||
SELECT
|
SELECT
|
||||||
@ -247,6 +248,9 @@ def blog_post(post_id):
|
|||||||
return render_template(v['blog']['post'], data=data)
|
return render_template(v['blog']['post'], data=data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/contact", methods=['GET', 'POST'])
|
@app.route("/contact", methods=['GET', 'POST'])
|
||||||
def contact():
|
def contact():
|
||||||
form = ContactForm()
|
form = ContactForm()
|
||||||
@ -524,6 +528,7 @@ def download_db():
|
|||||||
@app.route('/user/txt-editor')
|
@app.route('/user/txt-editor')
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
@validate_user_exists
|
@validate_user_exists
|
||||||
|
@cache.cached(timeout=43200)
|
||||||
def user_txteditor():
|
def user_txteditor():
|
||||||
template_name = v['tmp_user'].get('txt_editor')
|
template_name = v['tmp_user'].get('txt_editor')
|
||||||
return render_template(template_name, active_page='user_txteditor')
|
return render_template(template_name, active_page='user_txteditor')
|
||||||
@ -537,6 +542,9 @@ def save_post():
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
title = data['title']
|
title = data['title']
|
||||||
body = data['body']
|
body = data['body']
|
||||||
|
time = cur_date()
|
||||||
|
|
||||||
|
print(time)
|
||||||
|
|
||||||
soup = BeautifulSoup(body, 'html.parser')
|
soup = BeautifulSoup(body, 'html.parser')
|
||||||
body_no_img = soup.get_text(separator=' ', strip=True)
|
body_no_img = soup.get_text(separator=' ', strip=True)
|
||||||
@ -547,10 +555,10 @@ def save_post():
|
|||||||
t = None
|
t = None
|
||||||
if "id" in data:
|
if "id" in data:
|
||||||
q = 'UPDATE posts SET updated_at = %s, title = %s, body = %s, body_no_img = %s, lista_imagenes = %s::jsonb WHERE id = %s AND id_usr = %s;'
|
q = 'UPDATE posts SET updated_at = %s, title = %s, body = %s, body_no_img = %s, lista_imagenes = %s::jsonb WHERE id = %s AND id_usr = %s;'
|
||||||
t = (cur_date(), title, body, body_no_img, imagenes_json, data['id'], id_usr)
|
t = (time, title, body, body_no_img, imagenes_json, data['id'], id_usr)
|
||||||
else:
|
else:
|
||||||
q = "INSERT INTO posts (id_usr, created_at, title, body, body_no_img, lista_imagenes) VALUES (%s, %s, %s, %s, %s, %s::jsonb);"
|
q = "INSERT INTO posts (id_usr, created_at, title, body, body_no_img, lista_imagenes) VALUES (%s, %s, %s, %s, %s, %s::jsonb);"
|
||||||
t = (id_usr, cur_date(), title, body, body_no_img, imagenes_json)
|
t = (id_usr, time, title, body, body_no_img, imagenes_json)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dbUsers.update_data(q, t)
|
dbUsers.update_data(q, t)
|
||||||
@ -583,7 +591,7 @@ def my_posts():
|
|||||||
title,
|
title,
|
||||||
LEFT(body_no_img, 180),
|
LEFT(body_no_img, 180),
|
||||||
lista_imagenes->0,
|
lista_imagenes->0,
|
||||||
array_length(regexp_split_to_array(TRIM(body_no_img), '\s+'), 1) / 375 as n_words
|
GREATEST(array_length(regexp_split_to_array(TRIM(body_no_img), '\s+'), 1) / 375, 1) as n_words
|
||||||
FROM
|
FROM
|
||||||
posts
|
posts
|
||||||
WHERE
|
WHERE
|
||||||
@ -689,6 +697,11 @@ def metrics():
|
|||||||
@validate_user_exists
|
@validate_user_exists
|
||||||
@admin_required
|
@admin_required
|
||||||
def data_metrics():
|
def data_metrics():
|
||||||
|
# SELECT pv.id_post, pv.viewed, u.id, u.nombre, u.apellido
|
||||||
|
# FROM posts_visited pv
|
||||||
|
# INNER JOIN posts p ON p.id = pv.id_post
|
||||||
|
# INNER JOIN users u ON u.id = p.id_usr;
|
||||||
|
|
||||||
q_contact = r"""
|
q_contact = r"""
|
||||||
SELECT
|
SELECT
|
||||||
CASE EXTRACT(MONTH FROM full_date_time AT TIME ZONE 'America/Mexico_City')
|
CASE EXTRACT(MONTH FROM full_date_time AT TIME ZONE 'America/Mexico_City')
|
||||||
|
|||||||
50
static/e_blog/copy_url.js
Normal file
50
static/e_blog/copy_url.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { simpleNotification } from '../z_comps/notify.js';
|
||||||
|
|
||||||
|
const url = window.location.href;
|
||||||
|
const url_encoded = encodeURIComponent(url);
|
||||||
|
|
||||||
|
// Función reutilizable para abrir ventanas de compartir
|
||||||
|
function openShareWindow(shareUrl) {
|
||||||
|
window.open(shareUrl, '_blank', 'width=600,height=400,noopener,noreferrer');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copiar al portapapeles
|
||||||
|
const btn_copy = document.querySelector("button.copy");
|
||||||
|
if (btn_copy) {
|
||||||
|
btn_copy.addEventListener("click", async () => {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
simpleNotification("URL Copiada", "URL copiada", "success");
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error al copiar: ', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkedIn
|
||||||
|
const btn_in = document.querySelector("button.in");
|
||||||
|
if (btn_in) {
|
||||||
|
btn_in.addEventListener("click", () => {
|
||||||
|
const linkedInUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${url_encoded}`;
|
||||||
|
openShareWindow(linkedInUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Facebook
|
||||||
|
const btn_fb = document.querySelector("button.fb");
|
||||||
|
if (btn_fb) {
|
||||||
|
btn_fb.addEventListener("click", () => {
|
||||||
|
const fbShareUrl = `https://www.facebook.com/sharer/sharer.php?u=${url_encoded}`;
|
||||||
|
openShareWindow(fbShareUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// X / Twitter
|
||||||
|
const btn_x = document.querySelector("button.tw");
|
||||||
|
if (btn_x) {
|
||||||
|
btn_x.addEventListener("click", () => {
|
||||||
|
const tweetText = encodeURIComponent("Mira este post interesante:");
|
||||||
|
const xShareUrl = `https://twitter.com/intent/tweet?url=${url_encoded}&text=${tweetText}`;
|
||||||
|
openShareWindow(xShareUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
103
static/h_tmp_user/d_read_post/read_post.css
Normal file
103
static/h_tmp_user/d_read_post/read_post.css
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
.pst-cont{
|
||||||
|
width: 65%;
|
||||||
|
min-height: 80%;
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont {
|
||||||
|
margin: 2rem auto;
|
||||||
|
padding: 2rem;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
& h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #2c3e50;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-weight: 700;
|
||||||
|
border-bottom: 2px solid #f0f0f0;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& span {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
& span i {
|
||||||
|
margin-right: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont > div:first-of-type {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilos para el contenido del post */
|
||||||
|
|
||||||
|
.pst-cont > div:last-of-type {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont p {
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: inter-word;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont .note-float-left,
|
||||||
|
.pst-cont .note-float-right {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont .note-float-left {
|
||||||
|
float: left;
|
||||||
|
margin-right: 1.5em;
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont .note-float-right {
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
margin-left: 1.5em;
|
||||||
|
max-width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont iframe {
|
||||||
|
max-width: 100%;
|
||||||
|
margin-left: auto !important;
|
||||||
|
margin-right: auto !important;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pst-cont::after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -72,37 +72,6 @@ document.querySelector('[name="title"]').value = title_post;
|
|||||||
|
|
||||||
|
|
||||||
// ENVIAR LOS NUEVOS CAMBIOS A LA BASE DE DATOS
|
// ENVIAR LOS NUEVOS CAMBIOS A LA BASE DE DATOS
|
||||||
|
|
||||||
// async function a_sendpost(title, body, id) {
|
|
||||||
// try {
|
|
||||||
// let response = await fetch('/user/save-post', {
|
|
||||||
// method: 'POST',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json'
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify({ "id": id, "title": title, "body": body}),
|
|
||||||
// credentials: 'include'
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// if (!response.ok) {
|
|
||||||
// throw new Error('Error en la respuesta del servidor <-');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const result = await response.json();
|
|
||||||
|
|
||||||
// simpleNotification('Éxito', `Publicación actualizada: ${result.title_post}`, 'success');
|
|
||||||
// // Opcional: Limpiar el editor después de guardar
|
|
||||||
// $('#summernote').summernote('code', '');
|
|
||||||
// document.querySelector("input[name='title']").value = '';
|
|
||||||
|
|
||||||
// } catch (error) {
|
|
||||||
// console.error('Error al guardar:', error);
|
|
||||||
// simpleNotification('Error', 'No se pudo guardar la publicación', 'error');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
async function a_sendpost(title, body, id) {
|
async function a_sendpost(title, body, id) {
|
||||||
try {
|
try {
|
||||||
let response = await fetch('/user/save-post', {
|
let response = await fetch('/user/save-post', {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
.form-control{
|
.form-control{
|
||||||
width: 100% !important;
|
width: 50% !important;
|
||||||
margin-bottom: 1em !important;
|
margin-bottom: 1em !important;
|
||||||
margin-top: 1em !important;
|
margin-top: 1em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-editor {
|
.note-editor {
|
||||||
width: 100% !important;
|
width: 50% !important;
|
||||||
min-height: 65vh !important;
|
min-height: 70vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-editable {
|
.note-editable {
|
||||||
@ -25,6 +25,7 @@ div.note-toolbar{
|
|||||||
|
|
||||||
div.note-editing-area {
|
div.note-editing-area {
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* aplica en la sección de edición del post */
|
/* aplica en la sección de edición del post */
|
||||||
@ -39,4 +40,3 @@ div.note-modal-backdrop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,12 +10,12 @@
|
|||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
<div class="container py-5">
|
<div class="container py-5" data-aos="fade-up" data-aos-delay="0" data-aos-duration="800">
|
||||||
<h2 class="text-center mb-4">Nuestra Metodología</h2>
|
<h2 class="text-center mb-4">Nuestra Metodología</h2>
|
||||||
<p class="text-center text-muted mb-5">Implementamos soluciones con enfoque humano, técnico y estratégico.</p>
|
<p class="text-center text-muted mb-5">Implementamos soluciones con enfoque humano, técnico y estratégico.</p>
|
||||||
|
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<div class="col-md-6" data-aos="fade-up" data-aos-delay="0" data-aos-duration="800">
|
<div class="col-md-6">
|
||||||
<div class="card shadow-sm h-100" style="border: 2px solid#90b83b;">
|
<div class="card shadow-sm h-100" style="border: 2px solid#90b83b;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title" style="color: #90b83b;"><i class="bi bi-bar-chart-line me-2"></i> ANÁLISIS DE DATOS</h5>
|
<h5 class="card-title" style="color: #90b83b;"><i class="bi bi-bar-chart-line me-2"></i> ANÁLISIS DE DATOS</h5>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6" data-aos="fade-up" data-aos-delay="200" data-aos-duration="800">
|
<div class="col-md-6">
|
||||||
<div class="card shadow-sm h-100" style="border: 2px solid#8c1f5a;">
|
<div class="card shadow-sm h-100" style="border: 2px solid#8c1f5a;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title" style="color: #8c1f5a;"><i class="bi bi-sliders me-2"></i> PERSONALIZACIÓN</h5>
|
<h5 class="card-title" style="color: #8c1f5a;"><i class="bi bi-sliders me-2"></i> PERSONALIZACIÓN</h5>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6" data-aos="fade-up" data-aos-delay="400" data-aos-duration="800">
|
<div class="col-md-6">
|
||||||
<div class="card shadow-sm h-100" style="border: 2px solid#5d9dd1;">
|
<div class="card shadow-sm h-100" style="border: 2px solid#5d9dd1;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title" style="color: #5d9dd1;"><i class="bi bi-people me-2"></i> EXPERIENCIA DE SERVICIO</h5>
|
<h5 class="card-title" style="color: #5d9dd1;"><i class="bi bi-people me-2"></i> EXPERIENCIA DE SERVICIO</h5>
|
||||||
@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6" data-aos="fade-up" data-aos-delay="600" data-aos-duration="800">
|
<div class="col-md-6">
|
||||||
<div class="card shadow-sm h-100" style="border: 2px solid#002e72;">
|
<div class="card shadow-sm h-100" style="border: 2px solid#002e72;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title" style="color: #002e72;"><i class="bi bi-graph-up-arrow me-2"></i> IMPACTO</h5>
|
<h5 class="card-title" style="color: #002e72;"><i class="bi bi-graph-up-arrow me-2"></i> IMPACTO</h5>
|
||||||
@ -51,7 +51,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-12" data-aos="fade-up" data-aos-delay="800" data-aos-duration="800">
|
<div class="col-md-12">
|
||||||
<div class="card shadow-sm h-100" style="border: 2px solid#707272;">
|
<div class="card shadow-sm h-100" style="border: 2px solid#707272;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title" style="color: #707272;"><i class="bi bi-arrow-repeat me-2"></i> SOSTENIBILIDAD DEL CAMBIO</h5>
|
<h5 class="card-title" style="color: #707272;"><i class="bi bi-arrow-repeat me-2"></i> SOSTENIBILIDAD DEL CAMBIO</h5>
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<form method="get" class="mb-4">
|
<form method="get" class="mb-4">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" name="q" placeholder="Buscar título, autor o contenido..." value="{{ search }}">
|
<input type="text" class="form-control" name="q" placeholder="Buscar título, autor o contenido..." value="{{ search }}">
|
||||||
@ -19,81 +21,75 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<!-- {# i pagination #} -->
|
<!-- {# i pagination #} -->
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
<ul class="pagination justify-content-center mt-4">
|
<ul class="pagination justify-content-center mt-4">
|
||||||
|
|
||||||
<!-- Anterior -->
|
<!-- Anterior -->
|
||||||
<li class="page-item {% if current_page <= 1 %}disabled{% endif %}">
|
<li class="page-item {% if current_page <= 1 %}disabled{% endif %}">
|
||||||
<a class="page-link" href="?page={{ current_page - 1 }}{% if search %}&q={{ search }}{% endif %}">Anterior</a>
|
<a class="page-link" href="?page={{ current_page - 1 }}{% if search %}&q={{ search }}{% endif %}">Anterior</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Páginas -->
|
<!-- Páginas -->
|
||||||
{% for page_num in range(1, total_pages + 1) %}
|
{% for page_num in range(1, total_pages + 1) %}
|
||||||
<li class="page-item {% if page_num == current_page %}active{% endif %}">
|
<li class="page-item {% if page_num == current_page %}active{% endif %}">
|
||||||
<a class="page-link" href="?page={{ page_num }}{% if search %}&q={{ search }}{% endif %}">
|
<a class="page-link" href="?page={{ page_num }}{% if search %}&q={{ search }}{% endif %}">
|
||||||
{{ page_num }}
|
{{ page_num }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<!-- Siguiente -->
|
<!-- Siguiente -->
|
||||||
<li class="page-item {% if current_page >= total_pages %}disabled{% endif %}">
|
<li class="page-item {% if current_page >= total_pages %}disabled{% endif %}">
|
||||||
<a class="page-link" href="?page={{ current_page + 1 }}{% if search %}&q={{ search }}{% endif %}">Siguiente</a>
|
<a class="page-link" href="?page={{ current_page + 1 }}{% if search %}&q={{ search }}{% endif %}">Siguiente</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<!-- {# f pagination #} -->
|
<!-- {# f pagination #} -->
|
||||||
|
|
||||||
<div class="row" data-aos="fade-up" data-aos-delay="0" data-aos-duration="800">
|
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4" id="card-container" data-aos="fade" data-aos-delay="0" data-aos-duration="800" data-aos-easing="ease-in-out">
|
||||||
|
|
||||||
|
<!-- {# adaptación #} -->
|
||||||
{% for post in data %}
|
{% for post in data %}
|
||||||
|
<div class="col card-wrapper">
|
||||||
|
<div class="card h-100">
|
||||||
|
<!-- {# img #} -->
|
||||||
|
<img src="{{ post[7] if post[7] else url_for('static', filename='y_img/other/no_img.png') }}"
|
||||||
|
class="card-img-top" alt="card image">
|
||||||
|
|
||||||
<div class="col-12 col-sm-8 col-md-6 col-lg-4" >
|
<div class="card-body d-flex flex-column">
|
||||||
<div class="card">
|
<div class="mb-3">
|
||||||
|
<!-- {# título #} -->
|
||||||
|
<!-- <h5 class="card-title">{{ post[5] }}</h5> -->
|
||||||
|
<a href="{{ url_for('blog_post', post_id = post[0] ) }}" class="btn btn-info"> <h5>{{post[5]}}</h5> </a> <br>
|
||||||
|
<small class="text-muted">
|
||||||
|
<!-- {# autor #} -->
|
||||||
|
<i class="bi bi-file-person-fill"></i> {{ post[1] }} {{ post[2] }} <br>
|
||||||
|
<!-- {# fecha creación #} -->
|
||||||
|
<i class="bi bi-calendar-week"></i> {{ post[3] }}<br>
|
||||||
|
<!-- {# if fecha actualización #} -->
|
||||||
|
{% if post[4] is not none %}
|
||||||
|
<i class="bi bi-arrow-repeat"></i> {{ post[4] }}<br>
|
||||||
|
{% endif %}
|
||||||
|
<!-- {# tiempo lectura #} -->
|
||||||
|
<i class="bi bi-clock"></i> {{ post[8] }} min. <br>
|
||||||
|
<i class="bi bi-eye"></i>
|
||||||
|
</small>
|
||||||
|
|
||||||
<img class="card-img" src="{{ post[7] if post[7] else url_for('static', filename='y_img/other/no_img.png') }}" alt="">
|
<!-- {# breve resumen #} -->
|
||||||
|
<p class="card-text">{{ post[6] }}...</p>
|
||||||
|
|
||||||
<!-- <div class="card-img-overlay"><a href="#" class="btn btn-light btn-sm">Cooking</a></div> -->
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="card-title">
|
|
||||||
<a href="{{ url_for('blog_post', post_id = post[0] ) }}" class="btn btn-info">
|
|
||||||
{{ post[5] }} <!-- {# título #} -->
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
<small class="text-muted cat">
|
|
||||||
<!-- {# autor #} -->
|
|
||||||
<i class="bi bi-person-circle"></i> {{ post[1] }} {{ post[2] }} <br>
|
|
||||||
<i class="bi bi-clock-history"></i> {{ post[8] }} Min.
|
|
||||||
<!-- <i class="far fa-clock text-info"></i> 30 minutes -->
|
|
||||||
<!-- <i class="fas fa-users text-info"></i> 4 portions -->
|
|
||||||
</small>
|
|
||||||
<!-- {# breve contenido #} -->
|
|
||||||
<p class="card-text">{{ post[6] }}...</p>
|
|
||||||
<!-- <a href="{{ post[0] }}" class="btn btn-info">
|
|
||||||
<i class="bi bi-eye-fill"></i>
|
|
||||||
</a> -->
|
|
||||||
</div>
|
|
||||||
<div class="card-footer text-muted d-flex justify-content-between bg-transparent border-top-0">
|
|
||||||
<div class="views">
|
|
||||||
<i class="bi bi-vector-pen"></i> {{ post[3] }}
|
|
||||||
{% if post[4] is not none %}
|
|
||||||
<i class="bi bi-arrow-repeat"></i> {{ post[4] }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<!-- {#
|
<!-- <div class="mt-auto"></div> -->
|
||||||
<div class="stats">
|
|
||||||
<i class="bi bi-eye-fill"></i> No. Vistas
|
|
||||||
<i class="far fa-comment"></i> 12
|
|
||||||
</div>
|
|
||||||
#} -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- {# i pagination #} -->
|
<!-- {# i pagination #} -->
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{% extends 'template.html' %}
|
{% extends 'template.html' %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
|
<link rel="stylesheet" href="{{ url_for( 'static', filename='h_tmp_user/d_read_post/read_post.css' ) }}">
|
||||||
{% endblock css %}
|
{% endblock css %}
|
||||||
|
|
||||||
{% block navbar %}
|
{% block navbar %}
|
||||||
@ -9,73 +10,120 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.share {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #eee;
|
||||||
|
border-radius: 2rem;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: width 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
<h1>{{data[5]}}</h1>
|
.share:hover {
|
||||||
<h5>
|
width: 18rem;
|
||||||
<i class="bi bi-person-circle"></i> {{data[0]}} {{data[1]}} |
|
}
|
||||||
<i class="bi bi-pencil-square"></i> {{data[2]}} |
|
|
||||||
{% if data[3] is not none %}
|
.share__wrapper {
|
||||||
<i class="bi bi-arrow-repeat"></i> {{data[3]}} |
|
display: flex;
|
||||||
{% endif %}
|
align-items: center;
|
||||||
<i class="bi bi-clock-history"></i> {{ data[4] }} Minutos
|
height: 100%;
|
||||||
</h5>
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__toggle {
|
||||||
|
background: #549c67;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
margin: 0.25rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__button {
|
||||||
|
background: #555;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mostrar botones solo cuando se hace hover */
|
||||||
|
.share:hover .share__button {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fb { background: #1877f2; }
|
||||||
|
.tw { background: #000000; }
|
||||||
|
.in { background: #0077b5; }
|
||||||
|
.copy { background: #444; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="pst-cont">
|
||||||
|
<h1>{{data[5]}}</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<spam>
|
||||||
|
<a type="button" class="btn btn-secondary"><i class="bi bi-arrow-left"></i> Publicaciones</a> <br>
|
||||||
|
<i class="bi bi-person-circle"></i> {{data[0]}} {{data[1]}} |
|
||||||
|
<i class="bi bi-pencil-square"></i> {{data[2]}} |
|
||||||
|
{% if data[3] is not none %}
|
||||||
|
<i class="bi bi-arrow-repeat"></i> {{data[3]}} |
|
||||||
|
{% endif %}
|
||||||
|
<i class="bi bi-clock-history"></i> {{ data[4] }} Minutos |
|
||||||
|
<i class="bi bi-eye"></i>
|
||||||
|
</spam>
|
||||||
|
|
||||||
|
<div class="share">
|
||||||
|
<div class="share__wrapper">
|
||||||
|
<div class="share__toggle"><i class="bi bi-share-fill"></i></div>
|
||||||
|
<button href="#" class="share__button fb"><i class="bi bi-facebook"></i></button>
|
||||||
|
<button href="#" class="share__button tw"><i class="bi bi-twitter-x"></i></button>
|
||||||
|
<button class="share__button in"><i class="bi bi-linkedin"></i></button>
|
||||||
|
<button class="share__button copy"><i class="bi bi-link-45deg"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div >
|
||||||
|
{{data[6] | safe}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="width: 60vw;">
|
|
||||||
{{data[6] | safe}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- inicio pruebas scroll to up -->
|
|
||||||
<style>
|
|
||||||
#btn-subir {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 10%;
|
|
||||||
right: 5%;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #333;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 18px;
|
|
||||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-subir:hover {
|
|
||||||
background: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oculto {
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<button id="btn-subir" class="oculto">↑</button>
|
|
||||||
<script>
|
<script>
|
||||||
const btnSubir = document.getElementById('btn-subir');
|
document.querySelectorAll('.share__toggle').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
// Mostrar u ocultar el botón según el scroll
|
btn.closest('.share').classList.toggle('open');
|
||||||
window.addEventListener('scroll', () => {
|
});
|
||||||
if (window.scrollY > 300) { // Mostrar después de 300px de scroll
|
|
||||||
btnSubir.classList.remove('oculto');
|
|
||||||
} else {
|
|
||||||
btnSubir.classList.add('oculto');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Función para subir al inicio
|
|
||||||
btnSubir.addEventListener('click', () => {
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
behavior: 'smooth' // Desplazamiento suave
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<!-- fin pruebas -->
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
|
||||||
|
<script type="module" src="{{ url_for('static', filename='e_blog/copy_url.js') }}"></script>
|
||||||
|
|
||||||
|
<!-- {# flecha ir hasta arriba #} -->
|
||||||
|
{% include 'z_comps/arrow_to_up.html' %}
|
||||||
{% endblock js %}
|
{% endblock js %}
|
||||||
@ -1,48 +1,13 @@
|
|||||||
{% extends 'h_tmp_usr/z_tmp.html' %}
|
{% extends 'h_tmp_usr/z_tmp.html' %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
|
<link rel="stylesheet" href="{{ url_for( 'static', filename='h_tmp_user/d_read_post/read_post.css' ) }}">
|
||||||
{% endblock css %}
|
{% endblock css %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
|
|
||||||
.pst-cont{
|
|
||||||
|
|
||||||
width: 50% !important;
|
|
||||||
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
|
|
||||||
& img {
|
|
||||||
max-width: 100%; /* La imagen no superará el ancho del contenedor */
|
|
||||||
height: auto; /* Mantiene la proporción */
|
|
||||||
display: block; /* Elimina espacios no deseados debajo de la imagen */
|
|
||||||
}
|
|
||||||
|
|
||||||
& p {
|
|
||||||
text-align: justify !important;
|
|
||||||
text-justify: inter-word !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .note-float-left, .note-float-right{
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .note-float-left {
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .note-float-right{
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="pst-cont">
|
<div class="pst-cont">
|
||||||
<h1>{{data[2]}}</h1>
|
<h1>{{data[2]}}</h1>
|
||||||
@ -56,10 +21,14 @@
|
|||||||
<a type="button" class="btn btn-secondary" href="{{ url_for('edit_post', id_post= post_id ) }}"><i class="bi bi-vector-pen"></i> Editar.</a>
|
<a type="button" class="btn btn-secondary" href="{{ url_for('edit_post', id_post= post_id ) }}"><i class="bi bi-vector-pen"></i> Editar.</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{data[3] | safe}}
|
<div>
|
||||||
|
{{data[3] | safe}}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
@ -67,15 +36,4 @@
|
|||||||
{% include 'z_comps/arrow_to_up.html' %}
|
{% include 'z_comps/arrow_to_up.html' %}
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let cont = document.querySelector('div.pst-cont');
|
|
||||||
// let lst_img = cont.querySelectorAll('p img[style="width: 2515px;]');
|
|
||||||
let lst_img = cont.querySelectorAll('p img[style*="width: 2515px;"]');
|
|
||||||
lst_img.forEach(ele => {
|
|
||||||
console.log(ele);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock js %}
|
{% endblock js %}
|
||||||
@ -5,6 +5,8 @@
|
|||||||
<!-- {# estilos editor de texto #} -->
|
<!-- {# estilos editor de texto #} -->
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='h_tmp_user/text_editor.css' ) }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='h_tmp_user/text_editor.css' ) }}">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ url_for( 'static', filename='h_tmp_user/d_read_post/read_post.css' ) }}">
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/summernote@0.9.0/dist/summernote-lite.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/summernote@0.9.0/dist/summernote-lite.min.css" rel="stylesheet">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/summernote@0.9.0/dist/summernote-lite.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/summernote@0.9.0/dist/summernote-lite.min.js"></script>
|
||||||
@ -22,12 +24,23 @@
|
|||||||
<div id="summernote"></div>
|
<div id="summernote"></div>
|
||||||
<button type="submit" class="btn btn-success" id="btn-submit"><i class="bi bi-file-earmark-richtext-fill"></i> Enviar Cambios</button>
|
<button type="submit" class="btn btn-success" id="btn-submit"><i class="bi bi-file-earmark-richtext-fill"></i> Enviar Cambios</button>
|
||||||
<a class="btn btn-warning" href="{{ url_for('my_posts') }}" role="button" id="btn-cancel">Cancelar</a>
|
<a class="btn btn-warning" href="{{ url_for('my_posts') }}" role="button" id="btn-cancel">Cancelar</a>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- {# flecha ir hasta arriba #} -->
|
<!-- {# flecha ir hasta arriba #} -->
|
||||||
{% include 'z_comps/arrow_to_up.html' %}
|
{% include 'z_comps/arrow_to_up.html' %}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user