Added oldest and latest entry routes/buttons, added new poem entry, minor front end adjustments.

This commit is contained in:
Ada Werefox 2023-04-10 20:37:40 -05:00
parent dfeb15394a
commit c5e4cd605d
4 changed files with 312 additions and 62 deletions

File diff suppressed because one or more lines are too long

View File

@ -48,23 +48,70 @@ pub mod web_app_backend {
Some(_) => cookies.remove(Cookie::named("dark-mode")),
None => cookies.add(Cookie::new("dark-mode", "true")),
};
// let path_str = String::from(Path::new("/").join(path).to_str().expect("valid path"));
// let angy = path_str.as_str().to_owned();
Redirect::to("/")
}
#[get("/poem/<entry>?set-dark-mode")]
#[get("/poems")]
async fn poem_list(cookies: &CookieJar<'_>) -> Template {
let dark_mode = match cookies.get("dark-mode") {
Some(_) => true,
None => false,
};
let mut vdom = VirtualDom::new_with_props(void_app::PoemListPage, HomeProps {
dark_mode: dark_mode,
});
let _ = vdom.rebuild();
let output = dioxus_ssr::render(&vdom);
Template::render(
"index",
context! {
app_title: "A Letter to the Void",
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
test: &output,
dark_mode: match dark_mode {
true => "dark",
false => ""
},
},
)
}
#[get("/poems?set-dark-mode")]
async fn poems_dark_mode(cookies: &CookieJar<'_>) -> Redirect {
dark_mode(cookies, PathBuf::new()).await
}
#[get("/poems/<entry>?set-dark-mode")]
async fn entry_dark_mode(cookies: &CookieJar<'_>, entry: PathBuf) -> Redirect {
dark_mode(cookies, entry).await
}
async fn dark_mode(cookies: &CookieJar<'_>, entry: PathBuf) -> Redirect {
match cookies.get("dark-mode") {
Some(_) => cookies.remove(Cookie::named("dark-mode")),
None => cookies.add(Cookie::new("dark-mode", "true")),
};
let path_str = String::from(Path::new("/poem/").join(entry).to_str().expect("valid path"));
let path_str = String::from(Path::new("/poems/").join(entry).to_str().expect("valid path"));
let _angy = path_str.as_str().to_owned();
Redirect::to(path_str.as_str().to_owned().clone())
}
#[get("/poem/<entry>")]
#[get("/poems/latest")]
async fn latest_entry() -> Redirect {
let slug = void_app::get_latest_entry();
let uri = String::from("/poems/".to_string() + slug.as_str());
Redirect::to(uri)
}
#[get("/poems/oldest")]
async fn oldest_entry() -> Redirect {
let slug = void_app::get_oldest_entry();
let uri = String::from("/poems/".to_string() + slug.as_str());
Redirect::to(uri)
}
#[get("/poems/<entry>")]
async fn poem(cookies: &CookieJar<'_>, entry: &str) -> Template {
let dark_mode = match cookies.get("dark-mode") {
Some(_) => true,
@ -99,7 +146,7 @@ pub mod web_app_backend {
.mount("/images", FileServer::from("public/images"))
.mount("/styles", FileServer::from("public/styles"))
.mount("/fonts", FileServer::from("public/fonts"))
.mount("/", routes![dark_mode_root, index, dark_mode, poem])
.mount("/", routes![dark_mode_root, index, poems_dark_mode, poem_list, latest_entry, oldest_entry, entry_dark_mode, poem])
.attach(Template::fairing())
}
}

View File

@ -0,0 +1,75 @@
# Iced Coffee - Part 2
*(Author's note: The first part of this is exactly the same as my original poem, "Iced Coffee". I included it both as a way to directly show my own growth in the poem and for convenience.)*
*Iced coffee, on a cold Winter's day* \
*Iced coffee, bittersweet at the taste* \
*Do you see me? I probably fade* \
*Fade into darkness, and I'll go away*
Hmm....
*Why can't you see me? This mirror is broken* \
*Why can't you see me? I can't be this broken* \
*Every line keeping me from satisfaction* \
*I'm wondering why you can keep me in traction* \
*I'm falling, I'm sinking, this love is a sinkhole* \
*I don't understand why you keep me, this freakshow* \
*I see you and there's so much better contestants* \
*Competing and winning and gaining attention* \
*And I'm consolation, the prize for obsession* \
*Don't know why you'd even give me just a second*
*Iced coffee, on a cold Winter's day* \
*Iced coffee, bittersweet at the taste* \
*Do you see me? I probably fade* \
*Fade into darkness and I'll go away*
*Hmmmm....* \
*Hmmmm....* \
*Hmmmm....* **(it's like... I don't really even know why I bother)** \
*Hmmmm....* **(am I even worth paying attention to in the first place?)** \
*Hmmmm....* \
*Hmmmm....*
*Iced coffee, on a cold Winter's day* \
*Iced coffee, bittersweet at the taste* \
*Now you see me, and I'll be okay* \
*I have my darkness so far tucked away*
(chuckle)
*I never thought I would tell you I've accepted* \
*That I've resolved all of my feelings of shame* \
*I've moved on and found others who keep me present* \
*Remind me that being alone is okay* \
*I look back and think about that pain you caused me* \
*And realize I should have voiced my refrain* \
*You never owed me all your time and attention* \
*You never owed me anything, just the same*
*We both agree there are much bigger aggressions* \
*Than anger from feeling abandoned or strayed* \
*I'm happy to find some common resolution* \
*I'm happy we don't talk and I'm not afraid* \
*I feel so much better about my own presence* \
*I feel so much better and now I can say* \
*That drinking iced coffee no longer reminds me* \
*Of feeling isolated from your embrace* \
*So I wrote more verses to speak of acceptance* \
*I'm closing the book on that unhappy moment*
*Iced coffee, on a cold Winter's day* \
*Iced coffee, bittersweet at the taste* \
*Now you see me, and I'll be okay* \
*I have my darkness so far tucked away*
*Hmmmm....* \
*Hmmmm....* \
*Hmmmm....* **(I wrote "Iced Coffee" to express some feelings I had at the time)**\
*Hmmmm....* **(and while those feelings were valid. I realize now)**\
*Hmmmm....* **(that the insecurity I felt had more to do with my self-worth)**\
*Hmmmm....* **(and my reliance on needing someone to hold onto)**\
*Hmmmm....* **(in order to keep myself feeling happy and safe)**\
*Hmmmm....* **(I just wanted to express that I've grown since then)**\
*Hmmmm....* \
*Hmmmm....*

View File

@ -9,6 +9,7 @@
pub mod void_app {
// import the prelude to get access to the `rsx!` macro and the `Scope` and `Element` types
pub use dioxus::prelude::*;
use std::collections::VecDeque;
use markdown::{self, Options};
use rust_embed::RustEmbed;
@ -49,7 +50,7 @@ pub mod void_app {
cx.render(rsx! {
Router {
Route { to: "/", HomePage {} }
Route { to: "/poem/:slug/", PoemPage {} }
Route { to: "/poems/:slug/", PoemPage {} }
Route { to: "", PageNotFound {} }
}
})
@ -65,6 +66,115 @@ pub mod void_app {
/// Renders the app and returns the rendered Element.
pub fn HomePage(cx: Scope<HomeProps>) -> Element {
let dark_mode = cx.props.dark_mode.clone();
cx.render(rsx!{
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
div { class: "container space-y-4 mx-auto p-4",
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
p { class: "flex flex-row mx-auto max-w-full justify-center text-xl text-center",
"A Letter to the Void&nbsp;"
a { class: "max-h-sm",
href: "?set-dark-mode",
match dark_mode {
true => {
rsx! {
img { class: "",
src: "/images/white_square_button.png",
alt: "A white square button that can toggle dark mode.",
}
}
},
false => {
rsx! {
img { class: "",
src: "/images/black_square_button.png",
alt: "A black square button that can toggle dark mode.",
}
}
},
}
}
}
}
div { class: "flex p-4 ml-6 mr-6 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
p { class: "text-lg text-center",
"Welcome, and I hope you enjoy your stay!"
"\"A Letter to the Void\" is a passion project of mine in which I wrote poems about my past life experiences, present, and hopes for the future throughout my transition."
"The topics range from my feelings through transitioning (of course), past abuse, mental health exploration, and an overall journey to grow and become a better creature."
br {}
"I hope you enjoy the time you spend here, and sincerely, thank you."
br {}
br {}
"🖤 Alice Icehart Werefox"
}
}
div { class: "flex mx-auto max-w-full justify-center",
a { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/poems/latest",
div { class: "",
p { class: "text-xl text-center",
"See Latest Entry"
}
}
}
}
div { class: "flex mx-auto max-w-full justify-center",
a { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/poems/oldest",
div { class: "",
p { class: "text-xl text-center",
"See Oldest Entry"
}
}
}
}
div { class: "flex mx-auto max-w-full justify-center",
a { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/poems",
div { class: "",
p { class: "text-xl text-center",
"See All Entries"
}
}
}
}
div { class: "flex p-4 text-md text-center ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
}
}
}
})
}
fn get_poem_list() -> Vec<(String, String)> {
let mut poem_list = Vec::new();
for p in Poems::iter() {
let filename = p.to_string();
let poem_content = Poems::get(&filename).expect("Found poem {filename:?}");
let mut poem_to_str = std::str::from_utf8(poem_content.data.as_ref())
.expect("Title is valid UT8.")
.lines();
let title_markdown = poem_to_str.next().expect("No title specified.");
let title = markdown::to_html_with_options(title_markdown, &Options::gfm()).unwrap();
let slug = String::from(filename.trim_end_matches(".md"));
poem_list.push((title.clone(), slug.clone()));
}
log::trace!("{poem_list:?}");
poem_list
}
pub fn get_oldest_entry() -> String {
let mut poem_list = VecDeque::from(get_poem_list());
poem_list.pop_front().expect("There is an entry in this list of poems.").1
}
pub fn get_latest_entry() -> String {
let mut poem_list = get_poem_list();
poem_list.pop().expect("There is an entry in this list of poems.").1
}
/// Renders the app and returns the rendered Element.
pub fn PoemListPage(cx: Scope<HomeProps>) -> Element {
let dark_mode = cx.props.dark_mode.clone();
cx.render(rsx!{
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
@ -95,8 +205,24 @@ pub mod void_app {
}
}
}
a { class: "flex p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/",
div { class: "mx-auto max-w-full justify-center",
p { class: "text-lg text-center",
"Back to the homepage"
}
}
}
PoemList {}
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
a { class: "flex p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/",
div { class: "mx-auto max-w-full justify-center",
p { class: "text-lg text-center",
"Back to the homepage"
}
}
}
div { class: "flex p-4 text-md text-center ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
}
}
@ -104,23 +230,6 @@ pub mod void_app {
})
}
fn get_poem_list() -> Vec<(String, String)> {
let mut poem_list = Vec::new();
for p in Poems::iter() {
let filename = p.to_string();
let poem_content = Poems::get(&filename).expect("Found poem {filename:?}");
let mut poem_to_str = std::str::from_utf8(poem_content.data.as_ref())
.expect("Title is valid UT8.")
.lines();
let title_markdown = poem_to_str.next().expect("No title specified.");
let title = markdown::to_html_with_options(title_markdown, &Options::gfm()).unwrap();
let slug = String::from(filename.trim_end_matches(".md"));
poem_list.push((title.clone(), slug.clone()));
}
log::trace!("{poem_list:?}");
poem_list
}
fn PoemList(cx: Scope) -> Element {
let poem_list = get_poem_list();
cx.render(rsx! {
@ -141,14 +250,26 @@ pub mod void_app {
cx.render(rsx!{
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
div { class: "container space-y-4 mx-auto p-4",
a { href: "/",
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
p { class: "text-lg text-center",
"Take me back!"
a { class: "flex p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/",
div { class: "mx-auto max-w-full justify-center",
p { class: "text-lg text-center",
"Back to the homepage"
}
}
}
}
GetPoem { slug: slug, dark_mode: dark_mode }
a { class: "flex p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
href: "/",
div { class: "mx-auto max-w-full justify-center",
p { class: "text-lg text-center",
"Back to the homepage"
}
}
}
div { class: "p-4 text-md text-center ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
}
}
}
})
@ -168,11 +289,14 @@ pub mod void_app {
Link { to: "/"
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
p { class: "text-lg text-center",
"Take me back!"
"Back to the homepage"
}
}
}
GetPoem { slug: slug, dark_mode: dark_mode }
div { class: "p-4 text-md text-center ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
}
}
}
})
@ -184,9 +308,9 @@ pub mod void_app {
let slug = cx.props.slug.clone().expect("No slug specified.");
let slug_ref = slug.as_str();
cx.render(rsx!{
a { href: "/poem/{slug_ref}",
a { href: "/poems/{slug_ref}",
li { class: "p-4 ml-6 mr-6 ring-2 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
div { class: "text-lg text-center", "{title}" }
div { class: "text-xl text-center", "{title}" }
}
}
})
@ -198,7 +322,7 @@ pub mod void_app {
let slug = cx.props.slug.clone().expect("No slug specified.");
let slug_ref = slug.as_str();
cx.render(rsx!{
Link { to: "/poem/{slug_ref}",
Link { to: "/poems/{slug_ref}",
li { class: "p-4 ml-6 mr-6 ring-2 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
div { class: "mx-auto max-w-fit flex justify-center text-lg text-center",
dangerous_inner_html: "{title}"
@ -236,29 +360,31 @@ pub mod void_app {
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
let title = cx.props.title.clone().expect("No title specified.");
cx.render(rsx!{
span { class: "mx-auto max-w-fit flex justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
"{title}&nbsp;"
a { class: "max-h-sm",
href: "/poem/{slug}?set-dark-mode",
match dark_mode {
true => {
rsx! {
img { class: "",
src: "/images/white_square_button.png",
alt: "A white square button that can toggle dark mode.",
span { class: "p-4 ml-4 mr-4 flex text-xl text-center ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
span { class: "flex flex-row align-middle mx-auto max-w-full justify-center",
"{title}&nbsp;"
a { class: "",
href: "/poems/{slug}?set-dark-mode",
match dark_mode {
true => {
rsx! {
img { class: "",
src: "/images/white_square_button.png",
alt: "A white square button that can toggle dark mode.",
}
}
}
},
false => {
rsx! {
img { class: "",
src: "/images/black_square_button.png",
alt: "A black square button that can toggle dark mode.",
},
false => {
rsx! {
img { class: "",
src: "/images/black_square_button.png",
alt: "A black square button that can toggle dark mode.",
}
}
}
},
}
}
},
}
}
}
}
})
}
@ -273,10 +399,10 @@ pub mod void_app {
.clone()
.expect("This poem has an empty title.");
cx.render(rsx!{
p { class: "mx-auto max-w-fit flex flex-row justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
p { class: "mx-auto max-w-fit flex flex-row justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
dangerous_inner_html: "{title}&nbsp;",
a { class: "max-h-sm",
href: "/poem/{slug}?set-dark-mode",
a { class: "",
href: "/poems/{slug}?set-dark-mode",
match dark_mode {
true => {
rsx! {
@ -343,10 +469,12 @@ pub mod void_app {
cx.render(rsx!{
div { class: "flex-col space-y-4",
RenderPoemTitle { title: title.clone(), slug: slug, dark_mode: dark_mode }
details { class: "group mx-auto max-w-fit space-y-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
summary { class: "group-open:before:content-['Close'] before:content-['Open'] flex justify-center p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
div { class: "flex p-4 ml-6 mr-6 mx-auto max-w-full justify-center",
details { class: "group p-4 max-w-fit space-y-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-4 ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
summary { class: "group-open:before:content-['Close'] before:content-['Open'] flex justify-center p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
}
RenderPoemElement { content: content.clone(), creation_date: creation_date.clone() }
}
RenderPoemElement { content: content.clone(), creation_date: creation_date.clone() }
}
}
})