const std = @import("std");
const Pad = @import("./Pad.zig");
const httpz = @import("httpz");
const htmlUtf8ViewportStyle =
\\<!doctype html><html lang="en"><head>
\\<meta charset="UTF-8">
\\<meta name="viewport" content="width=device-width, initial-scale=1">
\\<style>body{max-width:800px;margin:0 auto;padding:8px;} p,ul{font-size:1.5em;} @media(prefers-color-scheme:dark){body{color:white;background:black;}a{color:#6d6dff}a:visited:{color:#c573ff;}}</style>
;
const hasSessionNav =
\\ <nav>
\\ <details>
\\ <summary>Navigate</summary>
\\ <a href="/logout">Log out</a>
\\ <a href="/a">Pads</a>
\\ <a href="/newpad">New pad</a>
\\ <a href="/deleteaccount">Delete account</a>
\\ </details>
\\ </nav>
;
const noSessionNav =
\\ <nav>
\\ <details>
\\ <summary>Navigate</summary>
\\ <a href="/login">Log in</a>
\\ <a href="/signup">Sign up</a>
\\ </details>
\\ </nav>
;
const adminPageOpen =
htmlUtf8ViewportStyle ++
\\<meta name="description" content="Login - pad">
\\<title>Admin page</title>
\\</head><body>
++ hasSessionNav ++
\\<h1>Admin page</h1>
\\<div>
;
const adminPageClose =
\\</div>
\\</body></html>
;
pub const newPadPage =
htmlUtf8ViewportStyle ++
\\<meta name="description" content="New pad">
\\<title>New pad</title>
\\</head><body>
++ hasSessionNav ++
\\<h1>New pad</h1>
\\ <form action="newpad" method="post">
++ iptSlug ++
iptContent ++
iptPadUser ++
iptPadPass ++
iptViews ++
iptDeleteAt ++
iptSubmit("Create new pad") ++
formClose;
pub fn login400(comptime val: []const u8) []const u8 {
const title: []const u8 = "Error " ++ val;
return htmlUtf8ViewportStyle ++
\\<meta name="description" content="
++ title ++
\\">
\\<title>
++ title ++
\\</title>
\\</head><body>
\\<h1>
++ title ++
\\</h1>
\\<p>actions:</p>
\\<ul>
\\<li><a href="/login">Log in</a></li>
\\<li><a href="/signup">Sign up</a></li>
\\</ul>
\\</body>
\\</html>
;
}
pub fn getLink(alloc: std.mem.Allocator, origin: []const u8, padLink: []const u8) ![]const u8 {
return try std.fmt.allocPrint(alloc, "{s}{s}{s}{s}/p/{s}{s}", .{ htmlUtf8ViewportStyle, metaTitle("Login"), "</head><body>", origin, padLink, "</body></html>" });
}
pub fn adminPage(alloc: std.mem.Allocator, user_pads: []Pad) ![]const u8 {
var list_pads: std.ArrayList([]const u8) = .empty;
for (user_pads) |ppad| {
// std.debug.print("name: {s}\n", .{ppad.slug});
try list_pads.append(alloc, try std.fmt.allocPrint(alloc, "<div>{s} <form style=\"display:inline\" method=\"post\" action=\"/a/{s}/delete\"><input type=\"submit\" name=\"submit\" value=\"del\"></form><a href=\"/a/{s}/getlink\">get link</a></div>", .{ ppad.slug, ppad.slug, ppad.slug }));
}
return try std.fmt.allocPrint(alloc, "{s}{s}{s}", .{ adminPageOpen, try std.mem.join(alloc, "\n", list_pads.items), adminPageClose });
}
const iptUser = "<p><label>Username: <input required name=username></label></p>";
const iptPw = "<p><label>Password: <input required name=password type=\"password\"></label></p>";
const iptCode = "<p><label>Code: <input required name=code type=\"password\"></label></p>";
const iptSlug = "<p><label>Slug: <input required name=slug></label></p>";
const iptContent = "<p><label>Content: <textarea rows=8 required name=content></textarea></label></p>";
const iptPadUser = "<p><label>Username (optional): <input name=username></label></p>";
const iptPadPass = "<p><label>Password (optional): <input name=password type=\"password\"></label></p>";
const iptViews = "<p><label>Max views (0 for unlimited): <input name=views_left min=0 type=number value=0></label></p>";
const iptDeleteAt = "<p><label>Unix timestamp to delete at (0 for never): <input min=0 name=delete_at type=number value=0></label></p>";
const formClose =
\\ </form>
\\ </body></html>
;
pub const loginForm =
htmlUtf8ViewportStyle ++
metaTitle("Login") ++
\\ </head><body>
++ noSessionNav ++
\\ <h1>Login page</h1>
\\ <form action="login" method="post">
++ iptUser ++
iptPw ++
iptSubmit("Log in") ++
formClose;
pub const signupFormBase = htmlUtf8ViewportStyle ++
metaTitle("Signup") ++
\\ </head><body>
++ noSessionNav ++
\\ <h1>Signup page</h1>
\\ <form action="signup" method="post">
++ iptUser ++
iptPw;
pub const signupForm = signupFormBase ++
iptSubmit("Sign up") ++
formClose;
pub const signupFormCode = signupFormBase ++
iptCode ++
iptSubmit("Sign up") ++
formClose;
pub const deleteAccountForm = simpleFormOpen("Delete account", "deleteaccount") ++
"<p>Are you sure you want to delete your account? This will also delete all associated pads.</p>" ++
iptSubmit("Delete Account") ++
formClose;
fn iptSubmit(comptime val: []const u8) []const u8 {
return "<p><input type=submit name=submit value=\"" ++ val ++ "\"></p>";
}
fn metaTitle(comptime str: []const u8) []const u8 {
return "<meta name=\"description\" content=\"" ++ str ++ "\">\n" ++ "<title>" ++ str ++ "</title>";
}
fn simpleFormOpen(comptime title: []const u8, comptime action: []const u8) []const u8 {
return htmlUtf8ViewportStyle ++
metaTitle("Signup") ++
\\</head><body>
++ hasSessionNav ++
\\<h1>
++ title ++
\\</h1>
\\<form action="
++ action ++
\\" method="post">
;
}
pub fn go(res: *httpz.Response, dest: []const u8) void {
std.log.info("go: {s}", .{dest});
res.status = 303;
res.header("Content-Type", "text/html; charset=utf-8");
res.header("Location", dest);
}