forked from andyburke/autonomous.contact
feature: switch everything to an invite-only model
This commit is contained in:
parent
a3302d2eff
commit
49c7a135d0
10 changed files with 445 additions and 3 deletions
|
|
@ -32,6 +32,76 @@
|
|||
document.addEventListener("topics_updated", update_topic_indicators);
|
||||
document.addEventListener("topic_changed", update_topic_indicators);
|
||||
document.addEventListener("user_logged_in", update_topic_indicators);
|
||||
|
||||
function generate_invite(click_event) {
|
||||
const button = click_event.target;
|
||||
|
||||
document.body.querySelectorAll(".invitepopover").forEach((element) => element.remove());
|
||||
|
||||
const invite_div = document.createElement("div");
|
||||
invite_div.classList.add("invitepopover");
|
||||
invite_div.innerHTML = `<form>
|
||||
<input name="code" type="text" placeholder="Custom code (optional)">
|
||||
<button onclick="create_invite(event);">Generate</button>
|
||||
</form>`;
|
||||
|
||||
document.body.appendChild(invite_div);
|
||||
invite_div.style.left = button.getBoundingClientRect().left + "px";
|
||||
invite_div.style.top = button.getBoundingClientRect().top + "px";
|
||||
}
|
||||
|
||||
async function create_invite(click_event) {
|
||||
click_event.preventDefault();
|
||||
|
||||
const button = click_event.target;
|
||||
const invite_popover = document.body.querySelector(".invitepopover");
|
||||
if (!invite_popover) {
|
||||
alert("Unknown error, try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
const user = document.body.dataset.user && JSON.parse(document.body.dataset.user);
|
||||
if (!user) {
|
||||
alert("You must be logged in.");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = button.closest("form");
|
||||
const code_input = form.querySelector('[name="code"]');
|
||||
|
||||
const invite_code_response = await api.fetch(`/api/users/${user.id}/invites`, {
|
||||
method: "POST",
|
||||
json: {
|
||||
code: code_input.value,
|
||||
},
|
||||
});
|
||||
|
||||
if (!invite_code_response.ok) {
|
||||
const error = await invite_code_response.json();
|
||||
return alert(error?.error?.message ?? error?.errors?.[0]?.message ?? "Unknown error.");
|
||||
}
|
||||
|
||||
const invite_code = await invite_code_response.json();
|
||||
|
||||
console.dir({
|
||||
invite_code,
|
||||
});
|
||||
|
||||
invite_popover.innerHTML = `
|
||||
<div>
|
||||
<div class="share-option">
|
||||
<span class="name">Code</span>
|
||||
<input readonly type="text" name="code" value="${invite_code.code}" />
|
||||
<button onclick="navigator.clipboard.writeText('${invite_code.code}');" />Copy</button>
|
||||
</div>
|
||||
<div class="share-option">
|
||||
<span class="name">Link</span>
|
||||
<input readonly type="text" name="code" value="${window.location.protocol + "//" + window.location.host + "/?invite_code=" + encodeURIComponent(invite_code.code)}" />
|
||||
<button onclick="navigator.clipboard.writeText('${window.location.protocol + "//" + window.location.host + "/?invite_code=" + encodeURIComponent(invite_code.code)}');" />Copy</button>
|
||||
</div>
|
||||
<button onclick="( () => document.querySelectorAll( '.invitepopover' ).forEach( (element) => element.remove() ) )()">Done</button>
|
||||
</div>`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
|
|
@ -147,6 +217,42 @@
|
|||
#sidebar .topic-list > li.topic.active a {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.invitepopover {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
background: var(--bg);
|
||||
margin: 1rem;
|
||||
border: 1px solid var(--border-normal);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.invitepopover .share-option .name {
|
||||
text-transform: uppercase;
|
||||
min-width: 4rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.share-option input {
|
||||
padding: 0.75rem;
|
||||
margin: 0 1rem 1rem 0;
|
||||
background: none;
|
||||
color: var(--text);
|
||||
border: 1px solid var(--border-highlight);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: none;
|
||||
font-size: large;
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.share-option button {
|
||||
padding: 1rem;
|
||||
text-transform: uppercase;
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--border-radius);
|
||||
margin-left: -0.75rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="sidebar">
|
||||
|
|
@ -381,6 +487,13 @@
|
|||
</details>
|
||||
</form>
|
||||
|
||||
<button
|
||||
style="text-transform: uppercase; width: 100%; padding: 1.1rem 0"
|
||||
onclick="generate_invite(event)"
|
||||
>
|
||||
Invite Another Human
|
||||
</button>
|
||||
|
||||
<form
|
||||
data-smart="true"
|
||||
data-method="DELETE"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue