This commit is contained in:
Adrian Woźniak 2024-10-25 17:13:01 +02:00
parent 2545d720b0
commit ac4cc26870
28 changed files with 8868 additions and 2066 deletions

50
Cargo.lock generated
View File

@ -56,7 +56,7 @@ dependencies = [
"actix-web",
"bitflags 2.6.0",
"bytes",
"derive_more",
"derive_more 0.99.18",
"futures-core",
"http-range",
"log",
@ -85,7 +85,7 @@ dependencies = [
"brotli",
"bytes",
"bytestring",
"derive_more",
"derive_more 0.99.18",
"encoding_rs",
"futures-core",
"h2",
@ -221,7 +221,7 @@ dependencies = [
"bytestring",
"cfg-if",
"cookie",
"derive_more",
"derive_more 0.99.18",
"encoding_rs",
"futures-core",
"futures-util",
@ -896,7 +896,9 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.6",
]
@ -1073,6 +1075,10 @@ dependencies = [
"actix-web",
"askama",
"askama_actix",
"chrono",
"derive_more 1.0.0",
"humantime",
"humantime-serde",
"migration",
"redis",
"rswind",
@ -1333,6 +1339,26 @@ dependencies = [
"syn 2.0.82",
]
[[package]]
name = "derive_more"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
]
[[package]]
name = "deunicode"
version = "1.6.0"
@ -1880,6 +1906,22 @@ dependencies = [
"libm",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "humantime-serde"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c"
dependencies = [
"humantime",
"serde",
]
[[package]]
name = "iana-time-zone"
version = "0.1.61"
@ -3227,7 +3269,7 @@ dependencies = [
"config",
"cssparser",
"cssparser-macros",
"derive_more",
"derive_more 0.99.18",
"either",
"enum_dispatch",
"globset",

View File

@ -19,5 +19,9 @@ uuid = { version = "1.11.0", features = ["v4", "v8"] }
migration = { path = "./migration" }
rswind = "0.0.1-alpha.1"
rswind_cli = "0.0.1-alpha.1"
derive_more = { version = "1.0.0", features = ["deref"] }
chrono = "0.4.38"
humantime = "2.1.0"
humantime-serde = "1.1.1"
[build-dependencies]

2212
assets/styles.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
fn main() {
let _ = std::fs::create_dir_all("./assets");
// let mut p = create_app();
// p.processor.options.watch = false;
// p.processor.options.parallel = true;

View File

@ -20,9 +20,9 @@ impl MigrationTrait for Migration {
.primary_key(),
)
.col(ColumnDef::new(Recipe::Title).string().not_null())
.col(ColumnDef::new(Recipe::ImageUrl).string())
.col(ColumnDef::new(Recipe::ImageUrl).string().not_null())
.col(ColumnDef::new(Recipe::Author).string())
.col(ColumnDef::new(Recipe::Time).string())
.col(ColumnDef::new(Recipe::Time).integer())
.col(ColumnDef::new(Recipe::Summary).string())
.to_owned(),
)
@ -42,7 +42,7 @@ impl MigrationTrait for Migration {
)
.col(ColumnDef::new(RecipeStep::Body).string().not_null())
.col(ColumnDef::new(RecipeStep::Hint).string())
.col(ColumnDef::new(RecipeStep::RecipeId).integer())
.col(ColumnDef::new(RecipeStep::RecipeId).integer().not_null())
.foreign_key(
&mut ForeignKeyCreateStatement::new()
.to_tbl(Recipe::Recipies)
@ -68,7 +68,12 @@ impl MigrationTrait for Migration {
)
.col(ColumnDef::new(RecipeIngredient::Name).string().not_null())
.col(ColumnDef::new(RecipeIngredient::Qty).integer().not_null())
.col(ColumnDef::new(RecipeIngredient::RecipeId).integer())
.col(ColumnDef::new(RecipeIngredient::Unit).string().not_null())
.col(
ColumnDef::new(RecipeIngredient::RecipeId)
.integer()
.not_null(),
)
.foreign_key(
&mut ForeignKeyCreateStatement::new()
.to_tbl(Recipe::Recipies)
@ -93,7 +98,7 @@ impl MigrationTrait for Migration {
.primary_key(),
)
.col(ColumnDef::new(RecipeTag::Name).string().not_null())
.col(ColumnDef::new(RecipeTag::RecipeId).integer())
.col(ColumnDef::new(RecipeTag::RecipeId).integer().not_null())
.foreign_key(
&mut ForeignKeyCreateStatement::new()
.to_tbl(Recipe::Recipies)
@ -154,6 +159,7 @@ enum RecipeIngredient {
Id,
Name,
Qty,
Unit,
RecipeId,
}

View File

@ -1 +1 @@
{"rustc_fingerprint":5966236372496131995,"outputs":{"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/eraden/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nub_checks\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.84.0-nightly (3ed6e3cc6 2024-10-17)\nbinary: rustc\ncommit-hash: 3ed6e3cc69857129c1d314daec00119ff47986ed\ncommit-date: 2024-10-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.84.0-nightly\nLLVM version: 19.1.1\n","stderr":""},"14371922958718593042":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/eraden/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nub_checks\nunix\n","stderr":""}},"successes":{}}
{"rustc_fingerprint":5966236372496131995,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.84.0-nightly (3ed6e3cc6 2024-10-17)\nbinary: rustc\ncommit-hash: 3ed6e3cc69857129c1d314daec00119ff47986ed\ncommit-date: 2024-10-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.84.0-nightly\nLLVM version: 19.1.1\n","stderr":""},"14371922958718593042":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/eraden/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nub_checks\nunix\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/eraden/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nub_checks\nunix\n","stderr":""}},"successes":{}}

View File

@ -1,5 +1,10 @@
{
"dependencies": {
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.15",
"postcss-import": "^16.1.0",
"tailwindcss": "^3.4.14"
},
"devDependencies": {

View File

@ -1 +1,2 @@
./node_modules/.bin/tailwindcss -i styles.css -o ./templates/styles.css
mkdir -p assets
./node_modules/.bin/tailwindcss -i ./templates/styles.css -o ./assets/styles.css

4
seed.sh Executable file
View File

@ -0,0 +1,4 @@
psql cooked postgres -h localhost < ./seed/recipies.sql
psql cooked postgres -h localhost < ./seed/recipe_tags.sql
psql cooked postgres -h localhost < ./seed/recipe_ingeredients.sql
psql cooked postgres -h localhost < ./seed/recipe_steps.sql

1000
seed/recipe_ingeredients.sql Normal file

File diff suppressed because it is too large Load Diff

4376
seed/recipe_steps.sql Normal file

File diff suppressed because it is too large Load Diff

1000
seed/recipe_tags.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,8 @@ pub struct Model {
pub id: i32,
pub name: String,
pub qty: i32,
pub recipe_id: Option<i32>,
pub unit: String,
pub recipe_id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -10,7 +10,7 @@ pub struct Model {
pub id: i32,
pub body: String,
pub hint: Option<String>,
pub recipe_id: Option<i32>,
pub recipe_id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -9,7 +9,7 @@ pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
pub recipe_id: Option<i32>,
pub recipe_id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -9,9 +9,9 @@ pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub title: String,
pub image_url: Option<String>,
pub image_url: String,
pub author: Option<String>,
pub time: Option<String>,
pub time: Option<i32>,
pub summary: Option<String>,
}

View File

@ -11,17 +11,19 @@ use sea_orm::{prelude::*, Database};
use std::str::FromStr;
mod entities;
mod filters {
pub fn duration(sec: &&i32) -> ::askama::Result<String> {
use humantime::format_duration;
use std::time::Duration;
#[derive(Debug, Template)]
#[template(path = "recipe_card.html")]
struct RecipeCard {
id: i32,
author: Option<String>,
image_url: String,
title: String,
time: Option<String>,
Ok(format_duration(Duration::from_secs(**sec as u64)).to_string())
}
}
#[derive(Debug, Template, derive_more::Deref)]
#[template(path = "recipe_card.html")]
struct RecipeCard(entities::recipies::Model);
#[derive(Debug, Template)]
#[template(path = "index.html")]
struct IndexTemplate {
@ -59,6 +61,13 @@ impl FromStr for Admins {
}
}
#[derive(Debug, serde::Deserialize)]
struct CreateRecipe {
// #[serde(default)]
// #[serde(with = "humantime_serde")]
// time: Option<chrono::Duration>,
}
#[derive(Debug, serde::Deserialize)]
struct SignIn {
login: String,
@ -129,21 +138,12 @@ async fn index_html(db: Data<DatabaseConnection>) -> IndexTemplate {
.await
.unwrap_or_default();
IndexTemplate {
recipies: recipies
.into_iter()
.map(|r| RecipeCard {
id: r.id,
author: r.author,
image_url: r.image_url.unwrap_or_default(),
title: r.title,
time: r.time,
})
.collect(),
recipies: recipies.into_iter().map(RecipeCard).collect(),
}
}
#[derive(Debug, Template)]
#[template(path = "recipies/show.html", print = "all")]
#[template(path = "recipies/show.html")]
struct RecipeDetailTemplate {
recipe: entities::recipies::Model,
tags: Vec<entities::recipe_tags::Model>,
@ -196,7 +196,7 @@ async fn show(id: Path<i64>, db: Data<DatabaseConnection>) -> impl Responder {
async fn styles_css() -> HttpResponse {
HttpResponse::Ok()
.append_header(("Content-Type", "text/css"))
.body(include_str!("../templates/styles.css"))
.body(include_str!("../assets/styles.css"))
}
#[actix_web::main]

View File

@ -1,19 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
.card {
@apply bg-white rounded overflow-hidden shadow-md relative;
}
.badge {
@apply bg-secondary-100 text-secondary-200 text-xs uppercase font-bold rounded-full p-2 absolute top-0 ml-2 mt-2;
}
.btn {
@apply rounded-full py-2 px-3 uppercase text-xs font-bold cursor-pointer tracking-wider;
}
*/

View File

@ -20,6 +20,11 @@
},
plugins: [
require('daisyui'),
require('postcss-import'),
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/nesting'),
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
],
daisyui: {
themes: ['light', 'dark'], // false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"]

View File

@ -9,7 +9,7 @@
{% block head %}{% endblock %}
</head>
<body class="text-gray-500 font-body">
<div class="grid md:grid-cols-4">
<div class="flex flex-col md:flex-row gap-4">
{% block navigation %}{% endblock %}
{% include "./nav.html" %}

View File

@ -1,25 +1,23 @@
{% extends "base.html" %}
{% block content %}
<main class="px-16 py-6 md:col-span-3">
<main class="md:col-span-3 flex flex-col gap-4 m-4">
<div class="flex justify-center md:justify-end">
<a href="/sign-in" class="btn text-primary border-primary md:border-2 hover:shadow-lg transition ease-out duration-300">Login</a>
</div>
<header>
<h2 class="text-gray-600 text-6xl font-semibold">Recipes</h2>
<h3 class="text-2xl font-semibold pl-1">For Techies</h3>
<header class="flex flex-col gap-2">
<h2 class="text-gray-600 text-6xl font-semibold text-center">Recipes</h2>
</header>
<div>
<h4 class="font-bold mt-12 pb-2 border-b border-gray-200">Latest Recipes</h4>
<div class="mt-8 grid md:grid-cols-3 gap-10">
<div class="flex flex-col gap-8">
<div class="flex flex-wrap gap-8 justify-center">
{% for recipe in recipies %}
{{ recipe|safe }}
{% endfor %}
</div>
<div class="flex justify-center mt-8">
<div class="flex justify-center">
<div class="btn bg-secondary-100 text-secondary-200 hover:shadow-inner transform hover:scale-110 hover:bg-opacity-60 transition ease-out duration-300">Load More</div>
</div>
</div>

View File

@ -1,5 +1,5 @@
<a class="card hover:shadow-lg transition ease-linear transform hover:scale-105" href="/recipe/{{id}}">
<img src={{image_url}} alt="noodles" class="w-full h-32 md:h-48 object-cover">
<a class="card hover:shadow-lg transition ease-linear transform hover:scale-105 shrink-0 grow-0 w-full md:w-[225px] lg:w-[400px]" href="/recipe/{{id}}">
<img src={{ image_url }} alt="noodles" class="w-full h-32 md:h-48 object-cover rounded-xl">
<div class="m-4">
<span class="font-bold">{{title}}</span>
{% match author %}
@ -10,12 +10,12 @@
</div>
{% match time %}
{% when Some with (time) %}
<div class="badge">
<div class="badge flex gap-2 p-4">
<svg class="w-5 inline-block" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="mt-2">{{time}}</span>
<span>{{time|duration}}</span>
</div>
{% when None %}
{% endmatch %}

View File

@ -1,49 +1,80 @@
{% extends "base.html" %}
{% block content %}
<main class="px-16 py-md:col-span-3">
<div class="flex justify-center md:justify-end">
<a href="/sign-in" class="btn text-primary border-primary md:border-2 hover:shadow-lg transition ease-out duration-300">Login</a>
<main class="m-4 flex flex-col gap-4 w-full">
{% include "../top_bar.html" %}
<div class="sm:rounded-3xl w-full flex flex-col gap-4">
<div class="text-center w-full">
<img src={{ recipe.image_url.clone() }} alt="{{recipe.title}}" class="rounded-xl w-40 md:w-72 ml-auto mr-auto">
</div>
<div class="sm:ml-auto sm:mr-auto sm:rounded-3xl">
<div class="sm:mx-auto text-center">
<img src={{ recipe.image_url.clone().unwrap_or_default() }} alt="{{recipe.title}}" class="sm:rounded-xl">
</div>
<div class="pl-[1.7rem] mt-8 sm:p-0 sm:mt-9">
<h1 class="font-young-serif text-[37px] text-stone-700 leading-10 mb-7 sm:text-stone-800">{{ recipe.title }}</h1>
<p class="text-[17px] pr-[15px] font-outfit-regular text-stone-500 sm:text-base sm:p-0">
<div class="flex flex-col gap-7">
<h1 class="font-young-serif text-desktop-heading-l text-stone-700 sm:text-stone-800 text-center md:text-left">
{{ recipe.title }}
</h1>
<p class="font-outfit-regular text-stone-500 sm:text-base">
{{ recipe.summary.clone().unwrap_or_default() }}
</p>
</div>
<div class="pr-7 border-bottom border-b-[2px] ml-auto mr-auto w-[20rem] pb-6 sm:w-auto">
<p class="Title mb-5">Ingredients</p>
<ul class="list-disc ml-6 marker:text-rose-900">
<div class="divider"></div>
<div class="flex flex-col gap-7">
<p class="text-desktop-heading-m">
Ingredients
</p>
<ul class="list-disc marker:text-rose-900 list-inside flex flex-col gap-3">
{% for ingeredient in ingeredients %}
<li class="paragraph pl-3 mb-2"><span class="mr-2">{{ ingeredient.qty }}</span><span>{{ ingeredient.name }}</span></li>
<li class="paragraph">
<span class="mr-1">
{{ ingeredient.qty }}
</span>
<span class="mr-4">
{{ ingeredient.unit }}
</span>
<span>
{{ ingeredient.name }}
</span>
</li>
{% endfor %}
</ul>
</div>
<div class="border-bottom marker:text-rose-900 marker:font-outfit-semibold border-b-[2px] ml-auto mr-auto w-[20.2rem] pb-4 mt-8 sm:w-auto">
<p class="Title mb-5">Instructions</p>
<ol class="list-decimal ml-6">
<div class="divider"></div>
<div class="marker:text-rose-900 marker:font-outfit-semibold flex flex-col gap-7">
<p class="text-desktop-heading-m">
Instructions
</p>
<ol class="list-decimal list-inside flex flex-col gap-3">
{% for step in steps %}
<li class="font-outfit-regular text-stone-500 text-[17px] mb-3 pl-3 text-base">
<li class="font-outfit-regular text-stone-500 text-base text-base">
{{ step.body }}
<div>{{ step.hint.clone().unwrap_or_default() }}</div>
</li>
{% endfor %}
</ol>
</div>
<div class="border-bottom marker:text-rose-900 marker:font-outfit-semibold border-b-[2px] ml-auto mr-auto w-[20.2rem] pb-4 mt-8 sm:w-auto">
<p class="Title mb-5">Tags</p>
<ol class="list-disc ml-6">
<div class="divider"></div>
<div class="marker:text-rose-900 marker:font-outfit-semibold flex flex-col gap-7">
<p class="text-desktop-heading-m">
Tags
</p>
<div class="flex gap-4 gap-7">
{% for tag in tags %}
<li class="font-outfit-regular text-stone-500 text-[17px] mb-3 pl-3 text-base">
<div>{{ tag.name }}</div>
</li>
<a class="bg-gray-300 dark:bg-gray-700 text-base text-gray-700 dark:text-white py-2 px-4 rounded-full font-bold hover:bg-gray-400 dark:hover:bg-gray-600 flex justify-center items-center">
{{ tag.name }}
</a>
{% endfor %}
</ol>
</div>
</div>
<div class="divider"></div>
<div class="marker:text-rose-900 marker:font-outfit-semibold flex flex-col gap-7">
<p class="text-desktop-heading-m">
Ingredients
</p>
<div class="flex gap-4 gap-7">
{% for ingeredient in ingeredients %}
<a class="bg-gray-300 dark:bg-gray-700 text-base text-gray-700 dark:text-white py-2 px-4 rounded-full font-bold hover:bg-gray-400 dark:hover:bg-gray-600 flex justify-center items-center">
{{ ingeredient.name }}
</a>
{% endfor %}
</div>
</div>
</div>
</main>

View File

@ -0,0 +1,6 @@
{% extends "../base.html" %}
{% block content %}
<form>
</form>
{% endblock %}

File diff suppressed because it is too large Load Diff

3
templates/top_bar.html Normal file
View File

@ -0,0 +1,3 @@
<div class="flex justify-center">
<a href="/sign-in" class="btn text-primary border-primary sm:border-2 hover:shadow-lg transition ease-out duration-300">Login</a>
</div>

View File

@ -77,6 +77,35 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@tailwindcss/aspect-ratio@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz#9ffd52fee8e3c8b20623ff0dcb29e5c21fb0a9ba"
integrity sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==
"@tailwindcss/forms@^0.5.9":
version "0.5.9"
resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.9.tgz#b495c12575d6eae5865b2cbd9876b26d89f16f61"
integrity sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==
dependencies:
mini-svg-data-uri "^1.2.3"
"@tailwindcss/nesting@^0.0.0-insiders.565cd3e":
version "0.0.0-insiders.565cd3e"
resolved "https://registry.yarnpkg.com/@tailwindcss/nesting/-/nesting-0.0.0-insiders.565cd3e.tgz#cdfe802dd2900cd6b4e99006c7d13b21132d72fc"
integrity sha512-WhHoFBx19TnH/c+xLwT/sxei6+4RpdfiyG3MYXfmLaMsADmVqBkF7B6lDalgZD9YdM459MF7DtxVbWkOrV7IaQ==
dependencies:
postcss-nested "^5.0.5"
"@tailwindcss/typography@^0.5.15":
version "0.5.15"
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.15.tgz#007ab9870c86082a1c76e5b3feda9392c7c8d648"
integrity sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==
dependencies:
lodash.castarray "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
@ -391,6 +420,21 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lodash.castarray@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lru-cache@^10.2.0:
version "10.4.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
@ -409,6 +453,11 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.3"
picomatch "^2.3.1"
mini-svg-data-uri@^1.2.3:
version "1.4.4"
resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
minimatch@^9.0.4:
version "9.0.5"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
@ -502,6 +551,15 @@ postcss-import@^15.1.0:
read-cache "^1.0.0"
resolve "^1.1.7"
postcss-import@^16.1.0:
version "16.1.0"
resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-16.1.0.tgz#258732175518129667fe1e2e2a05b19b5654b96a"
integrity sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==
dependencies:
postcss-value-parser "^4.0.0"
read-cache "^1.0.0"
resolve "^1.1.7"
postcss-js@^4, postcss-js@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
@ -517,6 +575,13 @@ postcss-load-config@^4.0.1:
lilconfig "^3.0.0"
yaml "^2.3.4"
postcss-nested@^5.0.5:
version "5.0.6"
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc"
integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==
dependencies:
postcss-selector-parser "^6.0.6"
postcss-nested@^6.0.1:
version "6.2.0"
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131"
@ -524,7 +589,15 @@ postcss-nested@^6.0.1:
dependencies:
postcss-selector-parser "^6.1.1"
postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1:
postcss-selector-parser@6.0.10:
version "6.0.10"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.1.1:
version "6.1.2"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==