Added the new link form and processing
This commit is contained in:
parent
c4bffa0387
commit
8341e64dfd
11 changed files with 261 additions and 45 deletions
149
Cargo.lock
generated
149
Cargo.lock
generated
|
|
@ -9,6 +9,7 @@ dependencies = [
|
|||
"askama",
|
||||
"axum",
|
||||
"bb8",
|
||||
"chrono",
|
||||
"clap",
|
||||
"cookie",
|
||||
"futures-util",
|
||||
|
|
@ -18,7 +19,6 @@ dependencies = [
|
|||
"rand_core",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"time",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-http",
|
||||
|
|
@ -69,6 +69,21 @@ version = "0.2.18"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
|
|
@ -310,6 +325,12 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
|
@ -334,6 +355,21 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.13"
|
||||
|
|
@ -396,6 +432,12 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
|
|
@ -463,7 +505,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -821,6 +862,29 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
|
|
@ -862,6 +926,16 @@ version = "1.0.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
|
@ -1640,6 +1714,7 @@ dependencies = [
|
|||
"atoi",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
"either",
|
||||
|
|
@ -1665,7 +1740,6 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sqlformat",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
|
|
@ -1723,6 +1797,7 @@ dependencies = [
|
|||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"crc",
|
||||
"digest",
|
||||
"dotenvy",
|
||||
|
|
@ -1750,7 +1825,6 @@ dependencies = [
|
|||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
|
@ -1765,6 +1839,7 @@ dependencies = [
|
|||
"base64",
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"crc",
|
||||
"dotenvy",
|
||||
"etcetera",
|
||||
|
|
@ -1789,7 +1864,6 @@ dependencies = [
|
|||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
|
@ -1801,6 +1875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"chrono",
|
||||
"flume",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
@ -1812,7 +1887,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"serde",
|
||||
"sqlx-core",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
"urlencoding",
|
||||
|
|
@ -2248,6 +2322,60 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.4"
|
||||
|
|
@ -2286,6 +2414,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
askama = "0.12.1"
|
||||
axum = "0.6"
|
||||
bb8 = "0.8.3"
|
||||
chrono = { version = "0.4.38", features = ["alloc", "serde"] }
|
||||
clap = { version = "4.5.13", features = ["derive"] }
|
||||
cookie = "0.18.1"
|
||||
futures-util = "0.3.30"
|
||||
|
|
@ -18,12 +19,11 @@ rand_chacha = "0.3.1"
|
|||
rand_core = "0.6.4"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
sqlx = { version = "0.7.4", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"postgres",
|
||||
"time",
|
||||
"chrono",
|
||||
"macros",
|
||||
"postgres",
|
||||
"runtime-tokio-rustls",
|
||||
] }
|
||||
time = { version = "0.3.36", features = ["macros", "serde"] }
|
||||
tokio = { version = "1.35.0", features = ["full"] }
|
||||
tower = "0.4.13"
|
||||
tower-http = { version = "0.4.4", features = ["fs"] }
|
||||
|
|
|
|||
|
|
@ -79,10 +79,7 @@ impl AuthState {
|
|||
.unwrap();
|
||||
|
||||
if let Some((id, admin)) = user {
|
||||
*store = Some(UserInfo {
|
||||
user_id: id,
|
||||
admin
|
||||
});
|
||||
*store = Some(UserInfo { user_id: id, admin });
|
||||
}
|
||||
}
|
||||
store.as_ref()
|
||||
|
|
@ -141,7 +138,9 @@ pub async fn post_signup(
|
|||
return Err(error_page(&SignupError::PasswordsDoNotMatch));
|
||||
}
|
||||
|
||||
let user_id = create_user(&signup.username, &signup.password, &pool).await.unwrap();
|
||||
let user_id = create_user(&signup.username, &signup.password, &pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let session_token = new_session(&pool, random, user_id).await;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
fs::{self, metadata},
|
||||
path::PathBuf,
|
||||
};
|
||||
use time::{macros::format_description, Date};
|
||||
use chrono::NaiveDate;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||
pub struct Article {
|
||||
|
|
@ -17,7 +17,7 @@ pub struct Article {
|
|||
pub content: String,
|
||||
pub previous: Option<String>,
|
||||
pub next: Option<String>,
|
||||
pub date: Date,
|
||||
pub date: NaiveDate,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ impl Article {
|
|||
let mut title: Option<String> = None;
|
||||
let mut previous: Option<String> = None;
|
||||
let mut next: Option<String> = None;
|
||||
let mut date: Option<Date> = None;
|
||||
let mut date: Option<NaiveDate> = None;
|
||||
let mut description: Option<String> = None;
|
||||
let mut lines: Vec<String> = super::read_lines(file_name);
|
||||
lines.reverse();
|
||||
|
|
@ -45,9 +45,8 @@ impl Article {
|
|||
} else if line.contains("next: ") {
|
||||
next = Some(line.clone().replace("next: ", ""));
|
||||
} else if line.contains("date: ") {
|
||||
let format = format_description!("[year]-[month]-[day]");
|
||||
date = Some(
|
||||
Date::parse(&line.clone().replace("date: ", ""), format).expect("not a date"),
|
||||
NaiveDate::parse_from_str(&line.clone().replace("date: ", ""), "%Y-%m-%d").expect("not a date"),
|
||||
);
|
||||
} else if line.contains("description: ") {
|
||||
description = Some(line.clone().replace("description: ", ""));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use crate::database::PsqlData;
|
||||
use chrono::NaiveDate;
|
||||
use futures_util::TryStreamExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{self, postgres::PgPool, Pool, Postgres};
|
||||
use std::{error::Error, path::Path};
|
||||
use time::{macros::format_description, Date};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, PartialOrd, Clone, sqlx::Type)]
|
||||
#[sqlx(type_name = "link_type", rename_all = "lowercase")]
|
||||
|
|
@ -20,7 +20,7 @@ pub struct Link {
|
|||
pub title: String,
|
||||
pub author: String,
|
||||
pub link_type: LinkType,
|
||||
pub date_added: Date,
|
||||
pub date_added: NaiveDate,
|
||||
}
|
||||
|
||||
impl Link {
|
||||
|
|
@ -30,7 +30,7 @@ impl Link {
|
|||
let mut title: Option<String> = None;
|
||||
let mut author: Option<String> = None;
|
||||
let mut link_type: Option<LinkType> = None;
|
||||
let mut date_added: Option<Date> = None;
|
||||
let mut date_added: Option<NaiveDate> = None;
|
||||
while lines.len() > 0 {
|
||||
let line: String = lines.pop().expect("Something went terribly wrong here");
|
||||
if line.contains("url: ") {
|
||||
|
|
@ -45,10 +45,8 @@ impl Link {
|
|||
_ => LinkType::ARTICLE,
|
||||
});
|
||||
} else if line.contains("date_added: ") {
|
||||
let format = format_description!("[year]-[month]-[day]");
|
||||
date_added = Some(
|
||||
Date::parse(&line.clone().replace("date_added: ", ""), format)
|
||||
.expect("not a date"),
|
||||
NaiveDate::parse_from_str(&line.clone().replace("date: ", ""), "%Y-%m-%d").expect("not a date"),
|
||||
);
|
||||
} else if line.contains("description: ") {
|
||||
description = Some(line.clone().replace("description: ", ""));
|
||||
|
|
|
|||
|
|
@ -1,20 +1,33 @@
|
|||
use core::panic;
|
||||
|
||||
use axum::{
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
routing::{get, Router},
|
||||
Extension,
|
||||
routing::{get, post, Router},
|
||||
Extension, Form,
|
||||
};
|
||||
use chrono::Local;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
auth::{AuthState, UserInfo},
|
||||
database::{
|
||||
link::{Link, LinkType},
|
||||
PsqlData,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::auth::{AuthState, UserInfo};
|
||||
|
||||
use super::templates::{AdminTemplate, HtmlTemplate};
|
||||
use super::{
|
||||
templates::{AdminTemplate, HtmlTemplate},
|
||||
NewLink,
|
||||
};
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new().route("/", get(get_admin))
|
||||
Router::new()
|
||||
.route("/", get(get_admin))
|
||||
.route("/new_link", post(new_link))
|
||||
}
|
||||
|
||||
pub async fn get_admin(
|
||||
Extension(mut current_user): Extension<AuthState>,
|
||||
) -> Response {
|
||||
pub async fn get_admin(Extension(mut current_user): Extension<AuthState>) -> Response {
|
||||
let user_info: UserInfo = current_user.get_user().await.unwrap().clone();
|
||||
if !user_info.admin {
|
||||
return Redirect::to("/").into_response();
|
||||
|
|
@ -22,6 +35,35 @@ pub async fn get_admin(
|
|||
HtmlTemplate(AdminTemplate {}).into_response()
|
||||
}
|
||||
|
||||
pub async fn new_link(
|
||||
Extension(mut current_user): Extension<AuthState>,
|
||||
Extension(pool): Extension<PgPool>,
|
||||
Form(new_item): Form<NewLink>,
|
||||
) -> Response {
|
||||
let user_info: UserInfo = current_user.get_user().await.unwrap().clone();
|
||||
if !user_info.admin {
|
||||
return Redirect::to("/").into_response();
|
||||
}
|
||||
|
||||
let new_link: Link = Link {
|
||||
id: 0,
|
||||
url: new_item.url,
|
||||
title: new_item.title,
|
||||
author: new_item.author,
|
||||
link_type: match &*new_item.link_type {
|
||||
"article" => LinkType::ARTICLE,
|
||||
"blog" => LinkType::BLOG,
|
||||
_ => panic!("Not a proper link type"),
|
||||
},
|
||||
description: get_trimmed_string(new_item.description),
|
||||
date_added: Local::now().date_naive(),
|
||||
};
|
||||
|
||||
let _ = new_link.insert(&pool).await;
|
||||
|
||||
Redirect::to("/admin").into_response()
|
||||
}
|
||||
|
||||
fn get_trimmed_string(input: String) -> Option<String> {
|
||||
if input.trim().is_empty() {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ use axum::{
|
|||
};
|
||||
|
||||
use super::templates::{
|
||||
ArchServerTemplate, BooksTemplate, CookingTemplate, CreationTemplate, EdgeDetectionTemplate, GardenTemplate, HtmlTemplate, TakTemplate, TechnologyTemplate, TimeTemplate
|
||||
ArchServerTemplate, BooksTemplate, CookingTemplate, CreationTemplate, EdgeDetectionTemplate,
|
||||
GardenTemplate, HtmlTemplate, TakTemplate, TechnologyTemplate, TimeTemplate,
|
||||
};
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
|
|
|
|||
|
|
@ -18,3 +18,12 @@ pub struct Signup {
|
|||
pub password: String,
|
||||
pub confirm_password: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct NewLink {
|
||||
pub url: String,
|
||||
pub description: String,
|
||||
pub title: String,
|
||||
pub author: String,
|
||||
pub link_type: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std:: sync::{Arc, Mutex};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use axum::{
|
||||
http::{Response, StatusCode},
|
||||
|
|
@ -22,9 +22,14 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
admin, blog::{self, get_articles_date_sorted}, garden, templates::{
|
||||
AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate, HtmlTemplate, InterestsTemplate, LinksPageTemplate, LoginTemplate, NowTemplate, ResumeTemplate, SignupTemplate, UsesTemplate, WorkTemplate
|
||||
}
|
||||
admin,
|
||||
blog::{self, get_articles_date_sorted},
|
||||
garden,
|
||||
templates::{
|
||||
AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate,
|
||||
HtmlTemplate, InterestsTemplate, LinksPageTemplate, LoginTemplate, NowTemplate,
|
||||
ResumeTemplate, SignupTemplate, UsesTemplate, WorkTemplate,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn get_router(pool: PgPool) -> Router {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,35 @@
|
|||
{% block content %}
|
||||
<h2>Admin</h2>
|
||||
<form action="/logout" method="post">
|
||||
<input type="submit" value="logout">
|
||||
<input type="submit" value="Logout">
|
||||
</form>
|
||||
<h3>New Link</h3>
|
||||
<form action="/admin/new_link" method="post">
|
||||
<p>
|
||||
<label for="title">Title:</label>
|
||||
<input type="text" name="title" id="title" required>
|
||||
</p>
|
||||
<p>
|
||||
<label for="author">Author:</label>
|
||||
<input type="text" name="author" id="author" required>
|
||||
</p>
|
||||
<p>
|
||||
<label for="url">URL:</label>
|
||||
<input type="text" name="url" id="url" required>
|
||||
</p>
|
||||
<p>
|
||||
<label for="link_type">Type:</label>
|
||||
<select name="link_type" id="link_type">
|
||||
<option value="blog">Blog</option>
|
||||
<option value="article">Article</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="description">Description:</label>
|
||||
<br>
|
||||
<textarea name="description" id="description" rows="5" columns="50">
|
||||
</textarea>
|
||||
</p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
<p>
|
||||
My admin page
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
<label for="password">Confirm Password: </label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" required>
|
||||
</p>
|
||||
<input type="submit" value="Login">
|
||||
<input type="submit" value="Signup">
|
||||
</form>
|
||||
</main>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Reference in a new issue