Create form
This commit is contained in:
parent
d8830fbbc0
commit
afc77b5c3d
1748
assets/styles.css
1748
assets/styles.css
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@ use serde::Deserialize;
|
|||||||
struct RecipeCard(entities::recipies::Model);
|
struct RecipeCard(entities::recipies::Model);
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "index.jinja")]
|
#[template(path = "index.jinja", ext = "html")]
|
||||||
struct IndexTemplate {
|
struct IndexTemplate {
|
||||||
recipies: Vec<RecipeCard>,
|
recipies: Vec<RecipeCard>,
|
||||||
count: u64,
|
count: u64,
|
||||||
@ -24,7 +24,7 @@ struct IndexTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "search.jinja")]
|
#[template(path = "search.jinja", ext = "html")]
|
||||||
struct SearchTemplate {
|
struct SearchTemplate {
|
||||||
recipies: Vec<RecipeCard>,
|
recipies: Vec<RecipeCard>,
|
||||||
count: u64,
|
count: u64,
|
||||||
@ -34,7 +34,7 @@ struct SearchTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "top_bar.jinja")]
|
#[template(path = "top_bar.jinja", ext = "html")]
|
||||||
struct TopBar<'s> {
|
struct TopBar<'s> {
|
||||||
session: &'s Option<User>,
|
session: &'s Option<User>,
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ impl<'s> TopBar<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "sign_in/form.jinja")]
|
#[template(path = "sign_in/form.jinja", ext = "html")]
|
||||||
struct SignInForm {
|
struct SignInForm {
|
||||||
not_found: bool,
|
not_found: bool,
|
||||||
email: String,
|
email: String,
|
||||||
@ -54,6 +54,19 @@ struct SignInForm {
|
|||||||
page: Page,
|
page: Page,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Template)]
|
||||||
|
#[template(path = "recipies/create_form.jinja", ext = "html")]
|
||||||
|
struct RecipeForm {
|
||||||
|
title: String,
|
||||||
|
summary: String,
|
||||||
|
ingeredients: String,
|
||||||
|
steps: String,
|
||||||
|
tags: String,
|
||||||
|
error: Option<String>,
|
||||||
|
session: Option<User>,
|
||||||
|
page: Page,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/sign-in")]
|
#[get("/sign-in")]
|
||||||
async fn render_sign_in() -> SignInForm {
|
async fn render_sign_in() -> SignInForm {
|
||||||
SignInForm {
|
SignInForm {
|
||||||
@ -209,7 +222,7 @@ async fn index_html(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "recipies/show.jinja")]
|
#[template(path = "recipies/show.jinja", ext = "html")]
|
||||||
struct RecipeDetailTemplate {
|
struct RecipeDetailTemplate {
|
||||||
recipe: entities::recipies::Model,
|
recipe: entities::recipies::Model,
|
||||||
tags: Vec<entities::recipe_tags::Model>,
|
tags: Vec<entities::recipe_tags::Model>,
|
||||||
@ -266,6 +279,20 @@ async fn show(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/create")]
|
||||||
|
async fn recipe_form(admin: Identity) -> RecipeForm {
|
||||||
|
RecipeForm {
|
||||||
|
title: "".into(),
|
||||||
|
summary: "".into(),
|
||||||
|
ingeredients: "".into(),
|
||||||
|
steps: "".into(),
|
||||||
|
tags: "".into(),
|
||||||
|
error: None,
|
||||||
|
session: admin.id().ok(),
|
||||||
|
page: Page::Index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/styles.css")]
|
#[get("/styles.css")]
|
||||||
async fn styles_css() -> HttpResponse {
|
async fn styles_css() -> HttpResponse {
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
@ -281,5 +308,6 @@ pub fn configure(config: &mut actix_web::web::ServiceConfig) {
|
|||||||
.service(index_html)
|
.service(index_html)
|
||||||
.service(show)
|
.service(show)
|
||||||
.service(search_page)
|
.service(search_page)
|
||||||
.service(search_results);
|
.service(search_results)
|
||||||
|
.service(recipe_form);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./templates/**/*.html"],
|
content: [
|
||||||
|
"./templates/**/*.html",
|
||||||
|
"./templates/**/*.jinja",
|
||||||
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
{% extends "base.jinja" %}
|
{% extends "base.jinja" %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.3/marked.min.js" integrity="sha512-kZ9BCD8vqCw2vJ1XG3EVZN5M5aRNxxMK3+uYuZPWc+TtW2Z1zSgmFlTIVHYHaWH0bH2lp2dUlB/1+M1h+lvfeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main class="md:col-span-3 flex flex-col gap-4 m-4 w-full">
|
<main class="md:col-span-3 flex flex-col gap-4 m-4 w-full">
|
||||||
{{ TopBar::new(session)|safe }}
|
{{ TopBar::new(session)|safe }}
|
||||||
@ -9,29 +13,77 @@
|
|||||||
</header>
|
</header>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div class="flex flex-wrap gap-8 justify-center">
|
<div class="flex flex-wrap gap-8 justify-center">
|
||||||
<form action="/search" method="post" class="flex flex-col gap-4">
|
<form action="/create" method="post" class="flex flex-col gap-4 md:w-1/2 md:mb-10">
|
||||||
<label for="title" class="flex gap-4">
|
<label for="title" class="flex gap-4">
|
||||||
<span>Title:</span>
|
<span class="w-24 shrink-0">Title:</span>
|
||||||
<input id="title" name="title" class="input border border-solid border-gray-200 rounded-lg" type="search" value="{{title}}" />
|
<input id="title" name="title" class="input border border-solid border-gray-200 rounded-lg" type="text" value="{{title}}" />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="summary" class="flex gap-4">
|
<label for="summary" class="flex gap-4">
|
||||||
<span>Summary:</span>
|
<span class="w-24 shrink-0">Summary:</span>
|
||||||
<textarea id="summary" name="summary" class="input border border-solid border-gray-200 rounded-lg" type="search" value="{{summary}}" />
|
<div class="flex gap-2 w-full">
|
||||||
|
<textarea id="summary" name="summary" class="textarea-with-view">{{summary}}</textarea>
|
||||||
|
<div class="content w-1/2"></div>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<blockquote class="w-full">
|
||||||
|
<p class="text-base font-semibold">Summary supports Markdown</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<label for="ingeredients" class="flex gap-4">
|
<label for="ingeredients" class="flex gap-4">
|
||||||
<span>Ingeredients:</span>
|
<span class="w-24 shrink-0">Ingeredients:</span>
|
||||||
<textarea id="ingeredients" name="ingeredients" class="input border border-solid border-gray-200 rounded-lg" type="search" value="{{summary}}" />
|
<div class="flex gap-2 w-full">
|
||||||
|
<textarea id="ingeredients" name="ingeredients" class="textarea-without-view">{{ingeredients}}</textarea>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<details class="w-full collapse collapse-arrow">
|
||||||
|
<summary class="text-base font-semibold collapse-title">Ingeredients should be listed as list of AMOUNT UNIT INGEREDIENT. Example:</summary>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1 font-normal collapse-content">
|
||||||
|
<div>1 KG Potato</div>
|
||||||
|
<div>200 G Sugar</div>
|
||||||
|
<div>3 Bananas</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
<label for="steps" class="flex gap-4">
|
<label for="steps" class="flex gap-4">
|
||||||
<span>Steps:</span>
|
<span class="w-24 shrink-0">Steps:</span>
|
||||||
<textarea id="steps" name="steps" class="input border border-solid border-gray-200 rounded-lg" type="search" value="{{summary}}" />
|
<div class="flex gap-2 w-full">
|
||||||
|
<textarea id="steps" name="steps" class="textarea-with-view">{{steps}}</textarea>
|
||||||
|
<div class="content w-1/2"></div>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<div></div>
|
|
||||||
|
<details class="w-full">
|
||||||
|
<summary class="text-base font-semibold">Syntax for steps:</summary>
|
||||||
|
<div>
|
||||||
|
<p class="text-base"><code>*</code> is step</p>
|
||||||
|
<p class="text-base"><code>></code> is hint for step</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
<label for="tags" class="flex gap-4">
|
<label for="tags" class="flex gap-4">
|
||||||
<span>Tags:</span>
|
<span class="w-24 shrink-0">Tags:</span>
|
||||||
<textarea id="tags" name="tags" class="input border border-solid border-gray-200 rounded-lg" type="search" value="{{summary}}" />
|
<div class="flex gap-2 w-full">
|
||||||
|
<textarea id="tags" name="tags" class="textarea-with-view">{{tags}}</textarea>
|
||||||
|
<div class="content w-1/2"> </div>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
<div>
|
||||||
|
<input type="submit" class="btn w-full" value="Save" />
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<script type="module">
|
||||||
|
Array.from(document.body.querySelectorAll('textarea')).forEach(el => {
|
||||||
|
if (!el.parentElement.querySelector('.content')) return;
|
||||||
|
el.parentElement.querySelector('div').innerHTML = marked.parse(el.value);
|
||||||
|
el.addEventListener('keyup', () => {
|
||||||
|
el.parentElement.querySelector('div').innerHTML = marked.parse(el.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -39,3 +39,22 @@
|
|||||||
.text-mobile-heading-xxl {
|
.text-mobile-heading-xxl {
|
||||||
@apply text-5xl not-italic font-medium;
|
@apply text-5xl not-italic font-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
@apply p-4 my-4 border-s-4 border-gray-300 bg-gray-200 text-xl italic font-medium leading-relaxed text-gray-900 border-0 rounded-lg flex flex-col gap-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply bg-gray-400 text-white py-1 px-2 border-0 rounded-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content ul {
|
||||||
|
@apply list-inside list-decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea-with-view {
|
||||||
|
@apply min-h-40 input border border-solid border-gray-200 rounded-lg w-1/2;
|
||||||
|
}
|
||||||
|
.textarea-without-view {
|
||||||
|
@apply min-h-40 input border border-solid border-gray-200 rounded-lg w-full;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user