post card fragment
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
use crate::templates::PostCardTemplate;
|
||||||
|
use askama::Template;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@@ -25,4 +27,8 @@ impl PostEntry {
|
|||||||
Err(e) => anyhow::bail!(e),
|
Err(e) => anyhow::bail!(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render(&self) -> String {
|
||||||
|
PostCardTemplate { post: self }.render().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,3 +135,9 @@ You're receiving this because you subscribed to the zero2prod newsletter."#,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "../templates/post_card_fragment.html")]
|
||||||
|
pub struct PostCardTemplate<'a> {
|
||||||
|
pub post: &'a PostEntry,
|
||||||
|
}
|
||||||
|
|||||||
41
templates/post_card_fragment.html
Normal file
41
templates/post_card_fragment.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<article class="bg-white rounded-lg shadow-md border border-gray-200 hover:shadow-lg transition-shadow duration-200">
|
||||||
|
<a href="/posts/{{ post.post_id }}"
|
||||||
|
class="block p-6 hover:bg-gray-50 transition-colors duration-200">
|
||||||
|
<div class="flex items-start justify-between">
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<h2 class="text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors">{{ post.title }}</h2>
|
||||||
|
<div class="flex items-center text-sm text-gray-500">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<svg class="w-4 h-4 mr-1"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
<time datetime="{{ post.published_at }}">
|
||||||
|
{{ post.formatted_date() }}
|
||||||
|
</time>
|
||||||
|
</div>
|
||||||
|
<span class="mx-2">•</span>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<svg class="w-4 h-4 mr-1"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||||
|
</svg>
|
||||||
|
<span>{{ post.author.as_deref().unwrap_or("Unknown") }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-shrink-0 ml-4">
|
||||||
|
<svg class="w-5 h-5 text-gray-400 group-hover:text-blue-600 transition-colors"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</article>
|
||||||
@@ -21,49 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
{% for post in posts %}
|
{% for post in posts %}{{ post.render() | safe }}{% endfor %}
|
||||||
<article class="bg-white rounded-lg shadow-md border border-gray-200 hover:shadow-lg transition-shadow duration-200">
|
|
||||||
<a href="/posts/{{ post.post_id }}"
|
|
||||||
class="block p-6 hover:bg-gray-50 transition-colors duration-200">
|
|
||||||
<div class="flex items-start justify-between">
|
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<h2 class="text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors">{{ post.title }}</h2>
|
|
||||||
<div class="flex items-center text-sm text-gray-500">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg class="w-4 h-4 mr-1"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
<time datetime="{{ post.published_at }}">
|
|
||||||
{{ post.formatted_date() }}
|
|
||||||
</time>
|
|
||||||
</div>
|
|
||||||
<span class="mx-2">•</span>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg class="w-4 h-4 mr-1"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
||||||
</svg>
|
|
||||||
<span>{{ post.author.as_deref().unwrap_or("Unknown") }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-shrink-0 ml-4">
|
|
||||||
<svg class="w-5 h-5 text-gray-400 group-hover:text-blue-600 transition-colors"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</article>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-8 text-center">
|
<div class="mt-8 text-center">
|
||||||
<button class="bg-blue-600 text-white hover:bg-blue-700 font-medium py-3 px-6 rounded-md transition-colors">
|
<button class="bg-blue-600 text-white hover:bg-blue-700 font-medium py-3 px-6 rounded-md transition-colors">
|
||||||
|
|||||||
Reference in New Issue
Block a user