This commit is contained in:
parent
f62673d6a7
commit
85c98fac56
@ -117,7 +117,7 @@ For example this is the model of this blog post:
|
||||
Neat part of the _CMS_ are those widgets. In editor they will be presented by appropriate component as well as in the editor preview.
|
||||
I am very satisfied with it and I recommend it.
|
||||
|
||||
## What's next
|
||||
## What's next {#whats-next}
|
||||
|
||||
I've decided not to wait for perfect product and I want to release this blog as soon as possible. I will have same approach as with other products. Make a <abbr title="Minimum Viable Product">**MVP**</abbr> and then release features as they are done.
|
||||
I've put some features into _Github Projects Board_. I will very likely make a redesign with experimental layout changes. I'd like to experiment with colors and make the blog look distinguishable and personal while maintaining accessibility.
|
||||
|
@ -28,7 +28,7 @@ This week I've attended a [Rusty game jam #2](https://itch.io/jam/rusty-jam-2).
|
||||
|
||||
![Egg fetcher game preview](/images/uploads/screenshot-from-2022-06-26-22-37-16.png "Egg fetcher game preview")
|
||||
|
||||
[You can check the rusult built with WASM here.](/showcase/egg-fetcher/)
|
||||
[You can check the result built with WASM here.](/showcase/egg-fetcher/)
|
||||
|
||||
## What's up with the weeklys
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
---
|
||||
title: Panoramic
|
||||
displayed: true
|
||||
description: "*Panoramic* was a company focused on building a web application
|
||||
for data scientists to be able to create and share models and graphs in
|
||||
between each other."
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
@ -14,3 +11,6 @@ tags:
|
||||
- Data analytics
|
||||
featured: false
|
||||
---
|
||||
*Panoramic* was a company focused on building a web application
|
||||
for data scientists to be able to create and share models and graphs in
|
||||
between each other.
|
||||
|
@ -1,11 +1,6 @@
|
||||
---
|
||||
title: The Expert
|
||||
displayed: true
|
||||
description: _The Expert_ is a digital platform that connects clients to
|
||||
interior designers around the world. For experts, it allows **managing** their
|
||||
**portfolio and profile** and **schedule** in which they are open for
|
||||
**consultations**. Clients are able to view their profiles and book
|
||||
consultations.
|
||||
link: https://www.theexpert.com/
|
||||
cover_image: /images/uploads/the-expert-logo.svg
|
||||
classification: webapp
|
||||
@ -17,3 +12,8 @@ tags:
|
||||
- GraphQL
|
||||
featured: true
|
||||
---
|
||||
_The Expert_ is a digital platform that connects clients to
|
||||
interior designers around the world. For experts, it allows **managing** their
|
||||
**portfolio and profile** and **schedule** in which they are open for
|
||||
**consultations**. Clients are able to view their profiles and book
|
||||
consultations.
|
||||
|
@ -1,12 +1,13 @@
|
||||
---
|
||||
title: beinSports
|
||||
displayed: true
|
||||
description: "*beIN Sports* is a global network of sports channels jointly owned
|
||||
and operated by *Qatari Sports Investments*, an affiliate of *Al Jazeera Media
|
||||
Networks*"
|
||||
link: https://www.beinsports.com/en-us
|
||||
cover_image: /images/uploads/bein_logo.af017869.webp
|
||||
classification: website
|
||||
tags:
|
||||
- Freemarker
|
||||
featured: false
|
||||
---
|
||||
*beIN Sports* is a global network of sports channels jointly owned
|
||||
and operated by *Qatari Sports Investments*, an affiliate of *Al Jazeera Media
|
||||
Networks*
|
||||
|
@ -1,11 +1,12 @@
|
||||
---
|
||||
title: CK Vive
|
||||
displayed: true
|
||||
description: Websitefor *CK Vive* travel agency with a **custom CMS system** for
|
||||
managing travel destinations.
|
||||
cover_image: /images/uploads/ck_vive_logo.svg
|
||||
link: https://ckvive.sk/
|
||||
classification: website
|
||||
tags:
|
||||
- PHP
|
||||
featured: false
|
||||
---
|
||||
Websitefor *CK Vive* travel agency with a **custom CMS system** for
|
||||
managing travel destinations.
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
title: dev project test
|
||||
displayed: true
|
||||
description: Testing project
|
||||
displayed: false
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
featured: false
|
||||
---
|
||||
Testing project
|
||||
|
@ -1,8 +1,6 @@
|
||||
---
|
||||
title: Docker
|
||||
displayed: false
|
||||
description: An introduction to Docker containerization technology and how it
|
||||
differs from virtualization.
|
||||
cover_image: /images/uploads/docker-use-cases.png
|
||||
classification: presentation
|
||||
tags:
|
||||
@ -10,3 +8,5 @@ tags:
|
||||
- Docker
|
||||
featured: false
|
||||
---
|
||||
An introduction to Docker containerization technology and how it
|
||||
differs from virtualization.
|
||||
|
@ -1,9 +1,7 @@
|
||||
---
|
||||
title: FX Sales
|
||||
displayed: true
|
||||
description: "*Caplin FX Sales* allows sales people to **trade on behalf of
|
||||
their clients**. This needs to be an efficient workflow providing all the
|
||||
relevant information to the sales user"
|
||||
link: https://www.caplin.com/business/fx-sales
|
||||
cover_image: /images/uploads/fx_sales_screen2x.png
|
||||
classification: webapp
|
||||
tags:
|
||||
@ -12,3 +10,6 @@ tags:
|
||||
- Knockout
|
||||
featured: false
|
||||
---
|
||||
*Caplin FX Sales* allows sales people to **trade on behalf of
|
||||
their clients**. This needs to be an efficient workflow providing all the
|
||||
relevant information to the sales user
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
title: HeyLady!
|
||||
displayed: true
|
||||
description: A thriving online community supporting women to learn and practise
|
||||
speaking English.
|
||||
link: https://www.heylady.io/
|
||||
cover_image: /images/uploads/heyladylogo.svg
|
||||
classification: webapp
|
||||
tags:
|
||||
@ -14,3 +13,5 @@ tags:
|
||||
- PostgreSQL
|
||||
featured: false
|
||||
---
|
||||
A thriving online community supporting women to learn and practise
|
||||
speaking English.
|
||||
|
@ -1,8 +1,6 @@
|
||||
---
|
||||
title: Košice Peace Marathon
|
||||
displayed: true
|
||||
description: "*Košice Peace Marathon* is the oldest marathon in Europe and the
|
||||
third-oldest in the world."
|
||||
link: https://www.kosicemarathon.com/
|
||||
cover_image: /images/uploads/screenshot-from-2024-08-06-18-22-52.png
|
||||
classification: website
|
||||
@ -11,3 +9,5 @@ tags:
|
||||
- MySQL
|
||||
featured: false
|
||||
---
|
||||
*Košice Peace Marathon* is the oldest marathon in Europe and the
|
||||
third-oldest in the world.
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Livesport.tv
|
||||
displayed: false
|
||||
description: "*Livesport.tv* is a network of premium online sports channels,
|
||||
featuring all the top sports competitions from around the world."
|
||||
classification: website
|
||||
tags:
|
||||
- Freemarker
|
||||
featured: false
|
||||
---
|
||||
*Livesport.tv* is a network of premium online sports channels,
|
||||
featuring all the top sports competitions from around the world.
|
||||
|
@ -1,10 +1,6 @@
|
||||
---
|
||||
title: Manualogic
|
||||
displayed: false
|
||||
description: "*Manualogic* is a **single-page application** for product manual
|
||||
creators. It contains **custom web editor** and management system of
|
||||
**translatable pages, books** and **products.** Its main goal is to enable
|
||||
customers to get manuals of their products in digital form."
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
@ -12,3 +8,7 @@ tags:
|
||||
- RxJS
|
||||
featured: false
|
||||
---
|
||||
*Manualogic* is a **single-page application** for product manual
|
||||
creators. It contains **custom web editor** and management system of
|
||||
**translatable pages, books** and **products.** Its main goal is to enable
|
||||
customers to get manuals of their products in digital form.
|
||||
|
@ -1,8 +1,6 @@
|
||||
---
|
||||
title: Renaissance of hypermedia systems
|
||||
displayed: true
|
||||
description: A presentation about hypermedia systems, HTMX, HyperView, and the
|
||||
HATEOAS principles. 2024
|
||||
link: https://michalvankodev.github.io/presentation-renaissance-of-hypermedia-systems/#/intro
|
||||
cover_image: /images/uploads/screenshot-from-2024-08-06-19-01-03.png
|
||||
classification: presentation
|
||||
@ -12,3 +10,5 @@ tags:
|
||||
- HTMX
|
||||
featured: true
|
||||
---
|
||||
A presentation about hypermedia systems, HTMX, HyperView, and the
|
||||
HATEOAS principles. 2024
|
||||
|
@ -1,9 +1,7 @@
|
||||
---
|
||||
title: responzIO
|
||||
displayed: true
|
||||
description: "***responzIO*** is a smart, easy-to-use monitoring and automation
|
||||
system. The ultimate tool for various applications such as hydroponics,
|
||||
aquariums, and gardens."
|
||||
link: https://www.croptech.com/
|
||||
cover_image: /images/uploads/responzio.png
|
||||
classification: embedded
|
||||
tags:
|
||||
@ -12,3 +10,6 @@ tags:
|
||||
- NodeJS
|
||||
featured: false
|
||||
---
|
||||
***responzIO*** is a smart, easy-to-use monitoring and automation
|
||||
system. The ultimate tool for various applications such as hydroponics,
|
||||
aquariums, and gardens.
|
||||
|
@ -1,11 +1,11 @@
|
||||
---
|
||||
title: SHIP (Structured heard input process)
|
||||
displayed: true
|
||||
description: "*SHIP* is a web application for **editors** who actively **track
|
||||
trades offers and bids** on the commodity market."
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
- Angular
|
||||
featured: false
|
||||
---
|
||||
*SHIP* is a web application for **editors** who actively **track
|
||||
trades offers and bids** on the commodity market.
|
||||
|
@ -1,13 +1,13 @@
|
||||
---
|
||||
title: Signal Hub Manager
|
||||
displayed: true
|
||||
description: "*Signal Hub* is an end-to-end **Big Data analytics platform** for
|
||||
large enterprises. It accelerates the process of extracting insights and
|
||||
intelligence from large volumes of data, including data of different types and
|
||||
in different formats."
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
- React
|
||||
featured: false
|
||||
---
|
||||
*Signal Hub* is an end-to-end **Big Data analytics platform** for
|
||||
large enterprises. It accelerates the process of extracting insights and
|
||||
intelligence from large volumes of data, including data of different types and
|
||||
in different formats.
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Skosy
|
||||
displayed: false
|
||||
description: "*Skosy* is a web application whose purpose is to **automate the
|
||||
writing of integration tests** for websites."
|
||||
classification: webapp
|
||||
tags:
|
||||
- Webapp
|
||||
featured: false
|
||||
---
|
||||
*Skosy* is a web application whose purpose is to **automate the
|
||||
writing of integration tests** for websites.
|
||||
|
@ -1,9 +1,7 @@
|
||||
---
|
||||
title: Spreading the Web
|
||||
displayed: true
|
||||
description: A presentation about the rising number of use cases for utilizing
|
||||
web technologies outside of the web platform such as native mobile
|
||||
applications and robotics. 2015
|
||||
link: https://michalvankodev.github.io/spreading-the-web
|
||||
cover_image: /images/uploads/screenshot-from-2024-08-06-18-48-02.png
|
||||
classification: presentation
|
||||
tags:
|
||||
@ -11,3 +9,6 @@ tags:
|
||||
- NodeJS
|
||||
featured: false
|
||||
---
|
||||
A presentation about the rising number of use cases for utilizing
|
||||
web technologies outside of the web platform such as native mobile
|
||||
applications and robotics. 2015
|
||||
|
@ -1,9 +1,6 @@
|
||||
---
|
||||
title: The Grand Escape
|
||||
displayed: true
|
||||
description: A videogame where you need to steer your boat to avoid obstacles
|
||||
and enemy bullets. The difficulty will be increased after a certain time and
|
||||
new enemies will be spawned to make your escape harder.
|
||||
link: https://michalvankodev.itch.io/the-grand-escape
|
||||
cover_image: /images/uploads/logo.png
|
||||
classification: videogame
|
||||
@ -12,3 +9,6 @@ tags:
|
||||
- Bevy
|
||||
featured: true
|
||||
---
|
||||
A videogame where you need to steer your boat to avoid obstacles
|
||||
and enemy bullets. The difficulty will be increased after a certain time and
|
||||
new enemies will be spawned to make your escape harder.
|
||||
|
@ -1,12 +1,13 @@
|
||||
---
|
||||
title: Unstoppable growth of front-end frameworks
|
||||
displayed: true
|
||||
description: A simple summary of the web front-end evolution. Describes how and
|
||||
why new tools in the NodeJS ecosystem improve & why there is still something
|
||||
to explore.
|
||||
link: https://michalvankodev.github.io/unstoppable-growth-of-frontend-frameworks/
|
||||
classification: presentation
|
||||
tags:
|
||||
- Presentation
|
||||
- NodeJS
|
||||
featured: false
|
||||
---
|
||||
A simple summary of the web front-end evolution. Describes how and
|
||||
why new tools in the NodeJS ecosystem improve & why there is still something
|
||||
to explore.
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
title: WebAssembly presentation
|
||||
displayed: true
|
||||
description: A presentation about what WebAssembly is about and how it might
|
||||
affect the future of the world.
|
||||
link: https://michalvankodev.github.io/presentation-webassembly/
|
||||
cover_image: /images/uploads/screenshot-from-2024-08-06-18-52-41.png
|
||||
classification: presentation
|
||||
tags:
|
||||
@ -10,3 +9,5 @@ tags:
|
||||
- WebAssembly
|
||||
featured: false
|
||||
---
|
||||
A presentation about what WebAssembly is about and how it might
|
||||
affect the future of the world.
|
||||
|
@ -35,7 +35,7 @@ rustflags = ["-Z", "threads=8"]
|
||||
# ]
|
||||
|
||||
[profile.dev]
|
||||
debug = false
|
||||
debug = true
|
||||
opt-level = 0
|
||||
# codegen-units = 16
|
||||
# lto = "thin"
|
||||
|
@ -46,7 +46,7 @@ wait_for_port:
|
||||
|
||||
# Kill the application running on port
|
||||
kill:
|
||||
kill $(lsof -t -i:{{port}})
|
||||
kill $(pidof axum_server)
|
||||
|
||||
# Clean the dist folder
|
||||
clean:
|
||||
|
@ -3,3 +3,4 @@ pub mod blog_post_list;
|
||||
pub mod blog_post_page;
|
||||
pub mod contact;
|
||||
pub mod index;
|
||||
pub mod project_list;
|
||||
|
29
axum_server/src/pages/project_list.rs
Normal file
29
axum_server/src/pages/project_list.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use askama::Template;
|
||||
use axum::http::StatusCode;
|
||||
|
||||
use crate::{
|
||||
components::site_header::HeaderProps,
|
||||
post_utils::{post_listing::get_post_list, post_parser::ParseResult},
|
||||
projects::project_model::ProjectMetadata,
|
||||
};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "project_list.html")]
|
||||
pub struct ProjectListTemplate {
|
||||
pub title: String,
|
||||
pub project_list: Vec<ParseResult<ProjectMetadata>>,
|
||||
pub header_props: HeaderProps,
|
||||
}
|
||||
|
||||
pub async fn render_projects_list() -> Result<ProjectListTemplate, StatusCode> {
|
||||
let mut project_list = get_post_list::<ProjectMetadata>("../_projects").await?;
|
||||
|
||||
project_list.retain(|project| project.metadata.displayed);
|
||||
project_list.reverse();
|
||||
|
||||
Ok(ProjectListTemplate {
|
||||
title: "Showcase".to_owned(),
|
||||
header_props: HeaderProps::default(),
|
||||
project_list,
|
||||
})
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
use core::panic;
|
||||
use std::path::Path;
|
||||
|
||||
use axum::http::StatusCode;
|
||||
@ -9,7 +10,7 @@ use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
|
||||
use syntect::{highlighting::ThemeSet, html::highlighted_html_for_string, parsing::SyntaxSet};
|
||||
use tokio::fs;
|
||||
use tracing::debug;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
use crate::picture_generator::{
|
||||
picture_markup_generator::generate_picture_markup, resolutions::get_max_resolution,
|
||||
@ -89,6 +90,7 @@ pub fn parse_html(markdown: &str, generate_images: bool) -> String {
|
||||
let syntax_set = SyntaxSet::load_defaults_newlines();
|
||||
let theme_set = ThemeSet::load_defaults();
|
||||
let theme = theme_set.themes.get("InspiredGitHub").unwrap();
|
||||
let mut heading_ended: Option<bool> = None;
|
||||
|
||||
let parser = Parser::new_ext(markdown, options).map(|event| match event {
|
||||
/*
|
||||
@ -181,15 +183,25 @@ pub fn parse_html(markdown: &str, generate_images: bool) -> String {
|
||||
text.to_lowercase()
|
||||
.replace(|c: char| !c.is_alphanumeric(), "-")
|
||||
});
|
||||
debug!("heading_id: {}", heading_id.clone());
|
||||
match heading_ended {
|
||||
None => {
|
||||
error!("Heading should have set state");
|
||||
panic!("Heading should have set state");
|
||||
}
|
||||
Some(true) => Event::Html(text),
|
||||
Some(false) => {
|
||||
heading_ended = Some(true);
|
||||
Event::Html(
|
||||
formatdoc!(
|
||||
r##"id="{heading_id}">
|
||||
{text}
|
||||
"##
|
||||
{text}"##
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Event::Text(text),
|
||||
},
|
||||
Event::Start(Tag::Heading {
|
||||
@ -199,7 +211,9 @@ pub fn parse_html(markdown: &str, generate_images: bool) -> String {
|
||||
attrs: _,
|
||||
}) => {
|
||||
let id_str = id.map(|id| id.to_string());
|
||||
debug!("heading_start: {:?}, level: {}", &id_str, level);
|
||||
text_kind = TextKind::Heading(id_str);
|
||||
heading_ended = Some(false);
|
||||
Event::Html(format!("<{level} ").into())
|
||||
}
|
||||
Event::Start(_) => event,
|
||||
@ -210,6 +224,7 @@ pub fn parse_html(markdown: &str, generate_images: bool) -> String {
|
||||
}
|
||||
Event::End(TagEnd::Heading(heading_level)) => {
|
||||
text_kind = TextKind::Text;
|
||||
heading_ended = None;
|
||||
Event::End(TagEnd::Heading(heading_level))
|
||||
}
|
||||
_ => event,
|
||||
|
@ -1,9 +1,6 @@
|
||||
use axum::http::StatusCode;
|
||||
|
||||
use crate::post_utils::{
|
||||
post_listing::get_post_list,
|
||||
post_parser::{parse_html, ParseResult},
|
||||
};
|
||||
use crate::post_utils::{post_listing::get_post_list, post_parser::ParseResult};
|
||||
|
||||
use super::project_model::ProjectMetadata;
|
||||
|
||||
@ -13,10 +10,6 @@ pub async fn get_featured_projects() -> Result<Vec<ParseResult<ProjectMetadata>>
|
||||
let featured_projects = project_list
|
||||
.into_iter()
|
||||
.filter(|post| post.metadata.featured)
|
||||
.map(|mut post| {
|
||||
post.metadata.description = parse_html(&post.metadata.description, false);
|
||||
post
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(featured_projects)
|
||||
|
@ -3,7 +3,6 @@ use serde::Deserialize;
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct ProjectMetadata {
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub classification: String,
|
||||
pub displayed: bool,
|
||||
pub cover_image: Option<String>,
|
||||
@ -18,6 +17,7 @@ pub fn translate_classification(classification: &str) -> &str {
|
||||
"website" => "Web site",
|
||||
"presentation" => "Presentation",
|
||||
"videogame" => "Video game",
|
||||
"embedded" => "Embedded system",
|
||||
any => any,
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
pages::{
|
||||
admin::render_admin, blog_post_list::render_blog_post_list,
|
||||
blog_post_page::render_blog_post, contact::render_contact, index::render_index,
|
||||
project_list::render_projects_list,
|
||||
},
|
||||
};
|
||||
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
|
||||
@ -16,6 +17,7 @@ pub fn get_router() -> Router {
|
||||
.route("/blog/tags/:tag", get(render_blog_post_list))
|
||||
.route("/blog/:post_id", get(render_blog_post))
|
||||
.route("/contact", get(render_contact))
|
||||
.route("/showcase", get(render_projects_list))
|
||||
.route("/admin", get(render_admin))
|
||||
.route("/feed.xml", get(render_rss_feed))
|
||||
.layer(
|
||||
|
@ -150,7 +150,11 @@ strong {
|
||||
|
||||
ul,
|
||||
ol {
|
||||
@apply px-4 my-2 text-slate-950 mx-auto max-w-read md:text-lg md:my-8 lg:text-readxl;
|
||||
@apply pl-10 pr-6 my-2 text-slate-950 mx-auto max-w-read md:text-lg md:my-8 lg:text-readxl lg:pl-14;
|
||||
|
||||
& p {
|
||||
@apply px-2;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
@ -204,83 +208,83 @@ article a {
|
||||
box-shadow:
|
||||
0px 0px 0 rgba(0, 255, 255, 0),
|
||||
0px 0px 0 rgba(255, 0, 255, 0);
|
||||
transform: translate(0, 0) skew(0deg, 0deg);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
10% {
|
||||
box-shadow:
|
||||
-3px -3px 0 rgba(0, 255, 255, 0.8),
|
||||
3px 3px 0 rgba(255, 0, 255, 0.8);
|
||||
transform: translate(-1px, -1px) skew(-0.5deg, -0.5deg);
|
||||
transform: translate(-1px, -1px);
|
||||
}
|
||||
|
||||
15% {
|
||||
box-shadow:
|
||||
2px -2px 0 rgba(0, 255, 255, 0.6),
|
||||
-2px 2px 0 rgba(255, 0, 255, 0.6);
|
||||
transform: translate(2px, -2px) skew(0.5deg, 0.5deg);
|
||||
transform: translate(2px, -2px);
|
||||
}
|
||||
|
||||
20% {
|
||||
box-shadow:
|
||||
-1px 1px 0 rgba(0, 255, 255, 0.4),
|
||||
1px -1px 0 rgba(255, 0, 255, 0.4);
|
||||
transform: translate(1px, 1px) scale(1.01);
|
||||
transform: translate(1px, 1px);
|
||||
}
|
||||
|
||||
25% {
|
||||
box-shadow:
|
||||
-4px 4px 0 rgba(0, 255, 255, 1),
|
||||
4px -4px 0 rgba(255, 0, 255, 1);
|
||||
transform: translate(-2px, 2px) skew(-0.5deg, -0.5deg);
|
||||
transform: translate(-2px, 2px);
|
||||
}
|
||||
|
||||
30% {
|
||||
box-shadow:
|
||||
3px -3px 0 rgba(0, 255, 255, 0.5),
|
||||
-3px 3px 0 rgba(255, 0, 255, 0.5);
|
||||
transform: translate(3px, -3px) scale(0.99);
|
||||
transform: translate(3px, -3px);
|
||||
}
|
||||
|
||||
40% {
|
||||
box-shadow:
|
||||
-2px 2px 0 rgba(0, 255, 255, 0.9),
|
||||
2px -2px 0 rgba(255, 0, 255, 0.9);
|
||||
transform: translate(-1px, 1px) skew(0.5deg, 0.5deg);
|
||||
transform: translate(-1px, 1px);
|
||||
}
|
||||
|
||||
50% {
|
||||
box-shadow:
|
||||
-1px -2px 0 rgba(0, 255, 255, 0.7),
|
||||
2px -1px 0 rgba(255, 0, 255, 0.7);
|
||||
transform: translate(1px, -1px) skew(-0.3deg, 0.3deg);
|
||||
transform: translate(1px, -1px);
|
||||
}
|
||||
|
||||
60% {
|
||||
box-shadow:
|
||||
2px -2px 0 rgba(0, 255, 255, 0.3),
|
||||
-2px 2px 0 rgba(255, 0, 255, 0.3);
|
||||
transform: translate(2px, -2px) scale(1.02);
|
||||
transform: translate(2px, -2px);
|
||||
}
|
||||
|
||||
75% {
|
||||
box-shadow:
|
||||
-3px 3px 0 rgba(0, 255, 255, 1),
|
||||
3px -3px 0 rgba(255, 0, 255, 1);
|
||||
transform: translate(-3px, 3px) skew(0.5deg, -0.5deg);
|
||||
transform: translate(-3px, 3px);
|
||||
}
|
||||
|
||||
85% {
|
||||
box-shadow:
|
||||
-2px -2px 0 rgba(0, 255, 255, 0.2),
|
||||
2px 2px 0 rgba(255, 0, 255, 0.2);
|
||||
transform: translate(-2px, -2px) scale(0.98);
|
||||
transform: translate(-2px, -2px);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow:
|
||||
0px 0px 0 rgba(0, 255, 255, 0),
|
||||
0px 0px 0 rgba(255, 0, 255, 0);
|
||||
transform: translate(0, 0) skew(0deg, 0deg);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -674,6 +674,10 @@ video {
|
||||
margin: 1.25rem;
|
||||
}
|
||||
|
||||
.m-6 {
|
||||
margin: 1.5rem;
|
||||
}
|
||||
|
||||
.mx-0\.5 {
|
||||
margin-left: 0.125rem;
|
||||
margin-right: 0.125rem;
|
||||
@ -709,11 +713,26 @@ video {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.my-3 {
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.my-5 {
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.my-6 {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.mb-1 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
@ -726,6 +745,10 @@ video {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mb-5 {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
@ -826,10 +849,6 @@ video {
|
||||
max-width: 64rem;
|
||||
}
|
||||
|
||||
.max-w-xl {
|
||||
max-width: 36rem;
|
||||
}
|
||||
|
||||
.flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
@ -884,6 +903,10 @@ video {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.gap-6 {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.self-start {
|
||||
align-self: flex-start;
|
||||
}
|
||||
@ -1703,8 +1726,11 @@ strong {
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
@ -1725,6 +1751,12 @@ strong {
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 3.5rem;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
ul,
|
||||
ol {
|
||||
@ -1734,6 +1766,13 @@ strong {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
& p {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
@ -1801,84 +1840,84 @@ article a:visited {
|
||||
box-shadow:
|
||||
0px 0px 0 rgba(0, 255, 255, 0),
|
||||
0px 0px 0 rgba(255, 0, 255, 0);
|
||||
transform: translate(0, 0) skew(0deg, 0deg);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
10% {
|
||||
box-shadow:
|
||||
-3px -3px 0 rgba(0, 255, 255, 0.8),
|
||||
3px 3px 0 rgba(255, 0, 255, 0.8);
|
||||
transform: translate(-1px, -1px) skew(-0.5deg, -0.5deg);
|
||||
transform: translate(-1px, -1px);
|
||||
}
|
||||
|
||||
15% {
|
||||
box-shadow:
|
||||
2px -2px 0 rgba(0, 255, 255, 0.6),
|
||||
-2px 2px 0 rgba(255, 0, 255, 0.6);
|
||||
transform: translate(2px, -2px) skew(0.5deg, 0.5deg);
|
||||
transform: translate(2px, -2px);
|
||||
}
|
||||
|
||||
20% {
|
||||
box-shadow:
|
||||
-1px 1px 0 rgba(0, 255, 255, 0.4),
|
||||
1px -1px 0 rgba(255, 0, 255, 0.4);
|
||||
transform: translate(1px, 1px) scale(1.01);
|
||||
transform: translate(1px, 1px);
|
||||
}
|
||||
|
||||
25% {
|
||||
box-shadow:
|
||||
-4px 4px 0 rgba(0, 255, 255, 1),
|
||||
4px -4px 0 rgba(255, 0, 255, 1);
|
||||
transform: translate(-2px, 2px) skew(-0.5deg, -0.5deg);
|
||||
transform: translate(-2px, 2px);
|
||||
}
|
||||
|
||||
30% {
|
||||
box-shadow:
|
||||
3px -3px 0 rgba(0, 255, 255, 0.5),
|
||||
-3px 3px 0 rgba(255, 0, 255, 0.5);
|
||||
transform: translate(3px, -3px) scale(0.99);
|
||||
transform: translate(3px, -3px);
|
||||
}
|
||||
|
||||
40% {
|
||||
box-shadow:
|
||||
-2px 2px 0 rgba(0, 255, 255, 0.9),
|
||||
2px -2px 0 rgba(255, 0, 255, 0.9);
|
||||
transform: translate(-1px, 1px) skew(0.5deg, 0.5deg);
|
||||
transform: translate(-1px, 1px);
|
||||
}
|
||||
|
||||
50% {
|
||||
box-shadow:
|
||||
-1px -2px 0 rgba(0, 255, 255, 0.7),
|
||||
2px -1px 0 rgba(255, 0, 255, 0.7);
|
||||
transform: translate(1px, -1px) skew(-0.3deg, 0.3deg);
|
||||
transform: translate(1px, -1px);
|
||||
}
|
||||
|
||||
60% {
|
||||
box-shadow:
|
||||
2px -2px 0 rgba(0, 255, 255, 0.3),
|
||||
-2px 2px 0 rgba(255, 0, 255, 0.3);
|
||||
transform: translate(2px, -2px) scale(1.02);
|
||||
transform: translate(2px, -2px);
|
||||
}
|
||||
|
||||
75% {
|
||||
box-shadow:
|
||||
-3px 3px 0 rgba(0, 255, 255, 1),
|
||||
3px -3px 0 rgba(255, 0, 255, 1);
|
||||
transform: translate(-3px, 3px) skew(0.5deg, -0.5deg);
|
||||
transform: translate(-3px, 3px);
|
||||
}
|
||||
|
||||
85% {
|
||||
box-shadow:
|
||||
-2px -2px 0 rgba(0, 255, 255, 0.2),
|
||||
2px 2px 0 rgba(255, 0, 255, 0.2);
|
||||
transform: translate(-2px, -2px) scale(0.98);
|
||||
transform: translate(-2px, -2px);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow:
|
||||
0px 0px 0 rgba(0, 255, 255, 0),
|
||||
0px 0px 0 rgba(255, 0, 255, 0);
|
||||
transform: translate(0, 0) skew(0deg, 0deg);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1957,10 +1996,6 @@ article a:visited {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.md\:grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.md\:h-16 {
|
||||
height: 4rem;
|
||||
}
|
||||
|
@ -42,15 +42,18 @@
|
||||
</section> <!-- /#socials -->
|
||||
|
||||
<section id="showcase" class="hidden lg:block">
|
||||
<h2 class="text-blue-950 font-bold text-2xl m-5 md:text-4xl">Showcase</h2>
|
||||
<h2 class="text-blue-950 font-bold text-2xl m-5 md:text-4xl"><a href="/showcase" class="text-blue-950 no-underline">Showcase</a></h2>
|
||||
|
||||
<ul class="">
|
||||
<ul class="mx-6">
|
||||
{% for project in featured_projects %}
|
||||
<li class="my-2">
|
||||
<li class="my-4">
|
||||
{% include "components/project_preview_card.html" %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<section class="text-center my-3 md:text-lg">
|
||||
<a href="/showcase">check out more projects</a>
|
||||
</section>
|
||||
</section> <!-- /#showcase -->
|
||||
</section> <!-- /#blog-container -->
|
||||
{% endblock %}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<section class="border rounded-md bg-white m-4 p-4 break-inside-avoid">
|
||||
<section class="border rounded-md bg-white p-4 break-inside-avoid">
|
||||
<header class="px-4 mb-3">
|
||||
<h2 class="text-xl font-semibold text-blue-900 md:text-2xl">
|
||||
{% match project.metadata.link %}
|
||||
@ -11,7 +11,7 @@
|
||||
{% endmatch %}
|
||||
</h2>
|
||||
<section class="description text-slate-800 my-2 md:text-xl text-justify">
|
||||
{{project.metadata.description|safe}}
|
||||
{{project.body|safe}}
|
||||
</section>
|
||||
</header>
|
||||
<!-- <hr class="border-blue-950 my-5"> -->
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% macro talent_card(svg, heading, description) %}
|
||||
|
||||
<section class="flex border rounded bg-white m-4 p-3 max-w-xl">
|
||||
<section class="flex border rounded bg-white m-4 p-3 max-w-[32rem]">
|
||||
<aside class="flex justify-center items-center pr-3">
|
||||
<svg aria-hidden="true" class="fill-blue-950 h-12 w-12 md:h-16 md:w-16">
|
||||
<use xlink:href="/svg/icons-sprite.svg#{{svg}}" />
|
||||
|
@ -61,6 +61,9 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<section class="text-center my-3 md:text-lg">
|
||||
<a href="/blog">see all blog posts</a>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="socials">
|
||||
|
24
axum_server/templates/project_list.html
Normal file
24
axum_server/templates/project_list.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<section id="project-list-container" class="max-w-maxindex mx-auto">
|
||||
<section id="project-list">
|
||||
{% if project_list.len() == 0 %}
|
||||
<p class="no-posts">You've found void in the space.</p>
|
||||
{% else %}
|
||||
<h1 class="m-5 text-4xl text-blue-950 font-extrabold md:text-6xl">
|
||||
Showcase
|
||||
</h1>
|
||||
|
||||
<ul class="m-6 grid grid-flow-row gap-6 md:grid-cols-2 md:grid-rows-[masonry] md:justify-stretch md:items-stretch xl:grid-cols-3">
|
||||
{% for project in project_list %}
|
||||
<li>
|
||||
{% include "components/project_preview_card.html" %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</section> <!-- /#project-list -->
|
||||
|
||||
</section> <!-- /#project-list-container -->
|
||||
{% endblock %}
|
@ -1,9 +1,13 @@
|
||||
<h2 class="text-blue-950 font-bold text-2xl m-5 md:text-4xl">Showcase</h2>
|
||||
<h2 class="text-blue-950 font-bold text-2xl m-5 md:text-4xl"><a href="/showcase" class="text-blue-950 no-underline">Showcase</a></h2>
|
||||
|
||||
<ul class="mx-5 md:grid md:grid-cols-2 md:grid-rows-[masonry] md:justify-stretch md:items-stretch xl:grid-cols-3">
|
||||
<ul class="mx-6 grid grid-flow-row gap-6 md:grid-cols-2 md:grid-rows-[masonry] md:justify-stretch md:items-stretch xl:grid-cols-3">
|
||||
{% for project in featured_projects %}
|
||||
<li class="my-2">
|
||||
<li>
|
||||
{% include "components/project_preview_card.html" %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<section class="text-center my-3 md:text-lg">
|
||||
<a href="/showcase">check out more projects</a>
|
||||
</section>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<footer>
|
||||
<footer class="my-4">
|
||||
<hr class="mb-4 border-slate-300 mx-5">
|
||||
<p
|
||||
class="text-center"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
|
@ -96,7 +96,7 @@ collections:
|
||||
widget: boolean,
|
||||
default: true,
|
||||
}
|
||||
- { label: Description, name: description, widget: markdown }
|
||||
- { label: Description, name: body, widget: markdown }
|
||||
- {
|
||||
label: Cover image,
|
||||
name: cover_image,
|
||||
@ -141,7 +141,7 @@ collections:
|
||||
widget: boolean,
|
||||
default: true,
|
||||
}
|
||||
- { label: Description, name: description, widget: markdown }
|
||||
- { label: Description, name: body, widget: markdown }
|
||||
- {
|
||||
label: Link,
|
||||
name: link,
|
||||
|
Loading…
Reference in New Issue
Block a user