view src/account.html.luan @ 3:b016e4b7c8da default tip

add read_me
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 12 Jul 2025 12:51:36 -0600
parents 8f4df159f06b
children
line wrap: on
line source

local Luan = require "luan:Luan.luan"
local error = Luan.error
local Html = require "luan:Html.luan"
local html_encode = Html.encode or error()
local Io = require "luan:Io.luan"
local Http = require "luan:http/Http.luan"
local Shared = require "site:/lib/Shared.luan"
local head = Shared.head or error()
local body_header = Shared.body_header or error()
local footer = Shared.footer or error()
local show_user_icons = Shared.show_user_icons or error()
local password_input = Shared.password_input or error()
local User = require "site:/lib/User.luan"
local Logging = require "luan:logging/Logging.luan"
local logger = Logging.logger "account.html"


return function()
	local user = User.current_required()
	if user==nil then return end
	local title = user.title
	local bio = user.bio
	local username = user.name
	local password = user.password
	local email = user.email
	local mp_id = user.mp_id
	Io.stdout = Http.response.text_writer()
%>
<!doctype html>
<html lang="en">
	<head>
<%		head() %>
		<title>Link My Style</title>
		<style>
			h1 {
				text-align: center;
			}
			div[body] {
				max-width: 600px;
				margin-left: auto;
				margin-right: auto;
			}
			@media (max-width: 700px) {
				div[body] {
					max-width: 90%;
				}
			}
			div[body] > * {
				margin-bottom: 64px;
			}
			h2 {
				margin-top: 20px;
				margin-bottom: 20px !important;
			}
			label {
				display: block;
			}
			div[field] {
				margin-bottom: 10px;
			}
			button[delete1] {
				background-color: red;
			}
			button[delete1]:hover,
			button[delete2]:hover {
				background-color: #7F1B1B;
			}
			div[delete2] {
				display: none;
			}

			div[pic] {
				display: flex;
				margin-bottom: 20px;
			}
			div[pic] img {
				width: 100px;
				height: 100px;
				object-fit: cover;
				border-radius: 50%;
				background-color: grey;
				flex-shrink: 0;
			}
			div[pic] div {
				width: 100%;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: space-around;
			}
			div[pic] button {
				width: 90%;
			}

			div[icons] div[list] {
				display: flex;
				gap: 5px;
				flex-wrap: wrap;
				margin-bottom: 8px;
			}
			span[icon] {
				border: 1px solid;
				display: flex;
				padding-right: 4px;
			}
			span[icon] img {
				display: block;
				height: 40px;
			}
			span[icon] > img {
				opacity: 0.3;
				touch-action: none;
			}
		</style>
		<script>
			'use strict';

			function delete1() {
				let delete2 = document.querySelector('div[delete2]');
				delete2.style.display = 'block';
				delete2.scrollIntoViewIfNeeded(false);
			}
			function undelete1() {
				document.querySelector('div[delete2]').style.display = 'none';
			}
			function delete2() {
				ajax( '/delete_user.js' );
			}

			function removePic() {
				let img = document.querySelector('div[pic] img');
				img.src = '/images/nothing.svg';
				let pic_uuid = document.querySelector('input[name="pic_uuid"]');
				pic_uuid.value = 'remove';
			}
			function uploaded(uuid,filename) {
				document.querySelector('input[name="pic_uuid"]').value = uuid;
				document.querySelector('input[name="pic_filename"]').value = filename;
				let img = document.querySelector('div[pic] img');
				img.src = uploadcareUrl(uuid);
			}
			function startUpload() {
				uploadcare.cropprOptions = {aspectRatio: 1};
				uploadcare.upload(uploaded);
			}

			dad.onDropped = function(event) {
				let dragging = event.original;
				if( iDragging === indexOf(dragging.parentNode.querySelectorAll(dropSelector),dragging) )
					return;
				let iconId = dragging.getAttribute('icon');
				let prev = dragging.previousElementSibling;
				let prevId = prev && prev.getAttribute('icon');
				ajax( '/move_icon.js?icon='+iconId+'&prev='+prevId );
			};
			dad.whatToDrag = function(draggable) {
				return draggable.parentNode;
			};
			function dragInit() {
				dropSelector = 'span[icon]';
				let items = document.querySelectorAll('span[icon] > img');
				for( let i=0; i<items.length; i++ ) {
					let item = items[i];
					dad.setDraggable(item);
					dad.setDropzone(item.parentNode);
				}
			}
		</script>
	</head>
	<body>
	<div full>
<%		body_header() %>
		<h1>My Account</h1>
		<div body>
			<form onsubmit="ajaxForm('/save_account.js',this)" action="javascript:">
				<h2>My information</h2>
				<div pic>
					<img src="<%= user.get_pic_url() or "/images/nothing.svg" %>">
					<div>
						<input type=hidden name="pic_uuid">
						<input type=hidden name="pic_filename">
						<button type=button big onclick="startUpload()">Pick an image</button>
						<button type=button big onclick="removePic()">Remove</button>
					</div>
				</div>
				<label>Profile Title</label>
				<div field>
					<input type=text name=title value="<%= html_encode(title or username) %>">
				</div>
				<label>Profile Bio</label>
				<div field>
					<textarea name=bio><%= html_encode(bio or "") %></textarea>
				</div>
				<label>Username</label>
				<div field>
					<input type=text required name=username placeholder="Username" value="<%= username %>">
					<div error=username></div>
				</div>
				<label>Password</label>
				<div field>
<%					password_input(password) %>
				</div>
				<button type=submit big>Save</button>
				<div error=success></div>
			</form>

<%
%>
			<h2 icons>Social icons</h2>
			<div icons>
<%				show_user_icons(user) %>
			</div>

			<form onsubmit="ajaxForm('/save_email.js',this)" action="javascript:">
				<h2>My email</h2>
				<label>Email</label>
				<div field>
					<input type=email required name=email placeholder="Email" value="<%= email %>">
					<div error=email></div>
				</div>
				<button type=submit big>Change</button>
			</form>

			<form onsubmit="ajaxForm('/save_mp.js',this)" action="javascript:">
				<h2>Custom analytics</h2>
				<label>Mixpanel Project Token</label>
				<div field>
					<input type=text name=mp_id value="<%= html_encode(mp_id or "") %>">
				</div>
				<button type=submit big>Save</button>
				<div error=success></div>
			</form>

			<div>
				<h2>Delete account</h2>
				<button type=button delete1 big onclick="delete1()">Delete account</button>
				<div delete2>
					<p>Are you sure that you want to delete this account?</p>
					<button type=button delete2 small onclick="delete2()">Yes</button>
					<button type=button small onclick="undelete1()">No</button>
				</div>
			</div>
		</div>
<%		footer() %>
	</div>
	</body>
	<script> dragInit(); </script>
</html>
<%
end