hero page, ingress form

This commit is contained in:
Per Stark committed 2024-12-30 23:57:13 +01:00
1 parent 981da5a649
commit a3bb73646c
17 files changed
+199 -73

No files matched your search

+1 -1
View File
@@ -1 +1 @@
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root,[data-theme]{background-color:var(--fallback-b1,oklch(var(--b1)/1));color:var(--fallback-bc,oklch(var(--bc)/1))}@supports not (color:oklch(0% 0 0)){:root{color-scheme:light;--fallback-p:#491eff;--fallback-pc:#d4dbff;--fallback-s:#ff41c7;--Line truncated
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root,[data-theme]{background-color:var(--fallback-b1,oklch(var(--b1)/1));color:var(--fallback-bc,oklch(var(--bc)/1))}@supports not (color:oklch(0% 0 0)){:root{color-scheme:light;--fallback-p:#491eff;--fallback-pc:#d4dbff;--fallback-s:#ff41c7;--Line truncated
+1
View File
@@ -13,6 +13,7 @@
packages = [
pkgs.openssl
pkgs.nodejs
pkgs.vscode-langservers-extracted
];
# https://devenv.sh/languages/
+5
View File
@@ -26,6 +26,7 @@ use zettle_db::{
html::{
account::{delete_account, set_api_key, show_account_page},
index::index_handler,
ingress::{process_ingress_form, show_ingress_form},
search_result::search_result_handler,
signin::{authenticate_user, show_signin_form},
signout::sign_out_user,
@@ -152,6 +153,10 @@ fn html_routes(
.route("/search", get(search_result_handler))
.route("/signout", get(sign_out_user))
.route("/signin", get(show_signin_form).post(authenticate_user))
.route(
"/ingress",
get(show_ingress_form).post(process_ingress_form),
)
.route("/account", get(show_account_page))
.route("/set-api-key", post(set_api_key))
.route("/delete-account", delete(delete_account))
+1 -1
View File
@@ -11,7 +11,7 @@ use crate::{
storage::types::user::User,
};
page_data!(IndexData, "index.html", {
page_data!(IndexData, "index/index.html", {
queue_length: u32,
user: Option<User>
});
+71
View File
@@ -0,0 +1,71 @@
use axum::{
extract::State,
http::{StatusCode, Uri},
response::{Html, IntoResponse, Redirect},
Form,
};
use axum_htmx::{HxBoosted, HxRedirect};
use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool;
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
use serde::{Deserialize, Serialize};
use surrealdb::{engine::any::Any, Surreal};
use tempfile::NamedTempFile;
use tracing::info;
use crate::{
error::ApiError,
server::AppState,
storage::types::{file_info::FileInfo, user::User},
};
use super::{render_block, render_template};
#[derive(Serialize)]
struct PageData {
// name: String,
}
pub async fn show_ingress_form(
State(state): State<AppState>,
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
) -> Result<impl IntoResponse, ApiError> {
if !auth.is_authenticated() {
return Ok(Redirect::to("/").into_response());
}
Ok(render_template("ingress_form.html", PageData {}, state.templates)?.into_response())
}
#[derive(Debug, TryFromMultipart)]
pub struct IngressParams {
pub content: Option<String>,
pub instructions: String,
pub category: String,
#[form_data(limit = "10000000")] // Adjust limit as needed
pub files: Vec<FieldData<NamedTempFile>>,
}
pub async fn process_ingress_form(
State(state): State<AppState>,
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
TypedMultipart(input): TypedMultipart<IngressParams>,
) -> Result<impl IntoResponse, ApiError> {
let user = match auth.current_user {
Some(user) => user,
None => return Ok(Redirect::to("/").into_response()),
};
info!("{:?}", input);
// Process files and create FileInfo objects
let mut file_infos = Vec::new();
for file in input.files {
let file_info = FileInfo::new(file, &state.surreal_db_client).await?;
file_infos.push(file_info);
}
// Process the ingress (implement your logic here)
Ok(Html("SuccessBRO!").into_response())
// Ok((HxRedirect::from(Uri::from_static("/")), StatusCode::OK).into_response())
}
+1
View File
@@ -5,6 +5,7 @@ use minijinja_autoreload::AutoReloader;
pub mod account;
pub mod index;
pub mod ingress;
pub mod search_result;
pub mod signin;
pub mod signout;
+1 -1
View File
@@ -34,7 +34,7 @@ pub async fn search_result_handler(
)
.await?;
Ok(Html("Hello".to_string()))
Ok(Html(answer.content))
// let output = state
// .tera
// .render(
+2 -2
View File
@@ -6,7 +6,7 @@
}
</style>
<div class="min-h-screen container mx-auto max-w-md flex justify-center flex-col">
<div class="min-h-screen container mx-auto px-4 sm:px-0 sm:max-w-md flex justify-center flex-col">
<h2 class="text-2xl font-bold text-center mb-8">Login to your account</h2>
<form hx-post="/signin" hx-target="#login-result">
@@ -42,4 +42,4 @@
<a href="/signup" hx-boost="true" class="link link-primary">Sign up</a>
</div>
</div>
{% endblock %}
{% endblock %}
+2 -2
View File
@@ -7,7 +7,7 @@
}
</style>
<div class="min-h-screen container mx-auto max-w-md flex justify-center flex-col">
<div class="min-h-screen container mx-auto px-4 sm:px-0 sm:max-w-md flex justify-center flex-col">
<h2 class="text-2xl font-bold text-center mb-8">Create your account</h2>
<form hx-post="/signup" hx-target="#signup-result" class="">
@@ -41,4 +41,4 @@
<a href="/signin" hx-boost="true" class="link link-primary">Sign in</a>
</div>
</div>
{% endblock %}
{% endblock %}
+4 -4
View File
@@ -6,16 +6,16 @@
<!-- Navbar -->
<nav class="navbar bg-base-200">
<div class="flex-1">
<a class="btn text-xl border-transparent btn-outline btn-primary" href="/">Minne</a>
<a class="btn text-2xl border-transparent btn-outline btn-primary" href="/">Minne</a>
</div>
<div>
<ul class="menu menu-horizontal px-1">
{% if user %}
<li><a hx-boost="true" href="/account">Account</a></li>
<li><a hx-boost="true" class="" href="/account">Account</a></li>
<li><a hx-boost="true" href="/signout">Sign out</a></li>
{% else %}
<li><a hx-boost="true" href="/signin">Login</a></li>
<li><a hx-boost="true" href="/signup">Sign up</a></li>
<li><a hx-boost="true" class="" href="/signin">Login</a></li>
<li><a hx-boost="true" class="" href="/signup">Sign up</a></li>
{% endif %}
</ul>
</div>
-27
View File
@@ -1,27 +0,0 @@
{% extends "head_base.html" %}
{% block body %}
<body class="min-h-screen">
<nav class="navbar bg-base-200">
<div class="flex-1">
<a class="btn text-xl border-transparent btn-outline btn-primary" href="/">Minne</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
{% if user %}
<li><a hx-boost="true" href="/account">Account</a></li>
<li><a hx-boost="true" href="/signout">Sign out</a></li>
{% else %}
<li><a hx-boost="true" href="/signin">Login</a></li>
<li><a hx-boost="true" href="/signup">Sign up</a></li>
{% endif %}
</ul>
</div>
</nav>
<main class="container mx-auto ">
{% block content %}{% endblock %}
</main>
</body>
{% endblock %}
-34
View File
@@ -1,34 +0,0 @@
{% extends "body_base.html" %}
{% block main %}
{% if user %}
<p class="text-blue-950">HI</p>
{% else %}
<div class="flex flex-col items-center justify-center min-h-[80vh] space-y-8">
<!-- Hero Section -->
<div class="text-center space-y-4 mb-8">
<h1
class="text-5xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-transparent bg-clip-text">
Welcome to minne
</h1>
<p class="text-gray-400 text-xl">
An experiment in creating a second brain
</p>
<p class="text-gray-400 text-lg">
There are {{queue_length}} messages queued for ingression.
</p>
</div>
<!-- Search Bar -->
<div class="w-full max-w-2xl">
<input type="text" placeholder="Enter your search query" class="input input-bordered w-full" name="query"
hx-get="/search" hx-target="#search-results" />
</div>
<!-- Search Results -->
<div id="search-results" class="w-full max-w-2xl mt-4">
<!-- Results will be populated here by HTMX -->
</div>
</div>
{% endif %}
{% endblock %}
+51
View File
@@ -0,0 +1,51 @@
<div class="hero">
<div class="hero-content text-center">
<div class="max-w-4xl space-y-8">
<!-- Hero Section -->
<h1
class="text-5xl sm:text-6xl py-4 pt-10 font-bold bg-gradient-to-r from-primary to-secondary text-transparent bg-clip-text">
Simplify Your Knowledge Management
</h1>
<p class="text-xl text-base-content/70">
Capture, connect, and retrieve your knowledge effortlessly with Minne
</p>
<!-- Features Grid -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 my-12">
<div class="card bg-base-100 shadow-hover">
<div class="card-body items-center">
<div class="skeleton h-32 w-32 rounded-full"></div>
<h3 class="card-title">Easy Capture</h3>
<p>Save anything instantly - texts, links, images, and more</p>
</div>
</div>
<div class="card bg-base-100 shadow-hover">
<div class="card-body items-center">
<div class="skeleton h-32 w-32 rounded-full"></div>
<h3 class="card-title">Smart Analysis</h3>
<p>AI-powered content analysis and organization</p>
</div>
</div>
<div class="card bg-base-100 shadow-hover">
<div class="card-body items-center">
<div class="skeleton h-32 w-32 rounded-full"></div>
<h3 class="card-title">Knowledge Graph</h3>
<p>Visualize connections between your ideas</p>
</div>
</div>
</div>
<!-- CTA -->
<div class="space-y-4">
<div class="flex justify-center gap-4">
<button class="btn btn-primary btn-lg">Get Started</button>
<button class="btn btn-outline btn-lg">Learn More</button>
</div>
<p class="text-sm text-base-content/60">
Currently processing {{queue_length}} items in queue
</p>
</div>
</div>
</div>
</div>
+8
View File
@@ -0,0 +1,8 @@
{% extends "body_base.html" %}
{% block main %}
{% if user %}
{% include 'index/signed_in_view.html' %}
{% else %}
{% include 'index/hero.html' %}
{% endif %}
{% endblock %}
+29
View File
@@ -0,0 +1,29 @@
<div class="container mx-auto p-4 max-w-screen-lg flex-col flex justify-center gap-6">
<!-- Search Bar -->
<div class="form-control w-full mx-auto mt-8">
<h1 class="textl-lg text-center pb-5">So here you can search all your ingressed documents</h1>
<input type="text" placeholder="Search your knowledge base" class="input input-bordered w-full" name="query"
hx-get="/search" hx-target="#search-results" />
<div id="search-results" class="mt-4">
<!-- Results will be populated here by HTMX -->
</div>
</div>
<!-- Recent Activity -->
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Recent Activity</h2>
<div class="skeleton h-32 w-full"></div>
</div>
</div>
<!-- Quick Actions - Modified button to link to ingress form -->
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Quick Actions</h2>
<div class="flex gap-4">
<a class="btn btn-primary" href="/ingress" hx-boost="true">Add Content</a>
</div>
</div>
</div>
</div>
+20
View File
@@ -0,0 +1,20 @@
{% extends "body_base.html" %}
{% block main %}
<div class="container px-4 max-w-screen-lg">
<form class="space-y-2" hx-post="/ingress" enctype="multipart/form-data">
<h1 class="text-2xl">Add content to the database </h1>
<label class="label label-text">Instructions</label>
<textarea name="instructions" class="textarea w-full input-bordered"
placeholder="Enter instructions for the AI here, help it understand what its seeing or how it should relate to the database"></textarea>
<label class="label label-text">Content (optional)</label>
<textarea name="content" class="textarea w-full input-bordered" placeholder="Additional content"></textarea>
<label class="label label-text">Category</label>
<input type="text" name="category" class="input input-bordered" placeholder="Category for ingress">
<label class="label label-text">Files</label>
<input type="file" name="files" multiple class="file-input file-input-bordered" />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div id="ingress-result"></div>
</div>
{% endblock %}
+2 -1
View File
@@ -3,5 +3,6 @@
\[x\] templating
\[x\] redirects
\[\] hx-redirect
\[\] macro for pagedata?
\[x\] macro for pagedata?
\[\] add more config structs for clarity
\[\] user id to fileinfo and data path?