Mercurial Hosting > linkmystyle
diff src/account.html.luan @ 0:8f4df159f06b
start public repo
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Jul 2025 20:57:49 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/account.html.luan Fri Jul 11 20:57:49 2025 -0600 @@ -0,0 +1,250 @@ +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