This commit is contained in:
2025-11-07 13:34:32 -08:00
commit 1e8c5a972b
436 changed files with 11000 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<div class="flex flex-column align-center gap txt-medium--responsive">
<% url = join_url(Current.account.join_code) %>
<label class="flex flex-column gap full-width txt-align-center">
<strong id="invite_label" class="invite-label">Share to invite more people</strong>
<span class="flex align-center gap margin-inline">
<input type="text" class="input fill-white" id="invite_url" value="<%= url %>" aria-labelledby="invite_label" readonly>
</span>
</label>
<div class="flex align-center gap">
<div data-controller="dialog" class="flex-inline">
<%= tag.button class: "btn", data: { action: "dialog#open" } do %>
<%= image_tag "qr-code.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Show join link QR code</span>
<% end %>
<dialog class="dialog panel shadow" data-dialog-target="menu"">
<%= qr_code_image(url) %>
<form method="dialog" class="margin-block-start flex justify-center">
<button class="btn">
<%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Close</span>
</button>
</form>
</dialog>
</div>
<%= button_to_copy_to_clipboard(url) do %>
<%= image_tag "copy-paste.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Copy join link</span>
<% end %>
<%= web_share_button(url, "Link to join Writebook", "Hit this link to join me in Writebook and start writing.") do %>
<%= image_tag "share.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Share join link</span>
<% end %>
<% if Current.user.can_administer? %>
<%= button_to account_join_code_path, class: "btn btn--regenerate" do %>
<%= image_tag "refresh.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Regenerate join link</span>
<% end %>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,48 @@
<div class="flex flex-column align-center gap txt-medium--responsive">
<% url = session_transfer_url(user.transfer_id) %>
<label class="flex flex-column gap full-width">
<div class="flex align-center gap">
<% if Current.user != user %>
<%= translation_button(:transfer_session) %>
<strong id="session_transfer_label" class="txt-align-start">Share to get them back into their account</strong>
<% else %>
<%= translation_button(:transfer_session_self) %>
<strong id="session_transfer_label" class="txt-align-start">Link to automatically log in on another device</strong>
<% end %>
</div>
<span class="flex align-center gap margin-inline">
<input type="text" class="input fill-white" id="session_transfer_url" value="<%= url %>" aria-labelledby="session_transfer_label" readonly>
</span>
</label>
<div class="flex align-center gap">
<div data-controller="dialog" class="flex-inline">
<%= tag.button class: "btn", data: { action: "dialog#open" } do %>
<%= image_tag "qr-code.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Show auto-login QR code</span>
<% end %>
<dialog class="dialog panel shadow" data-dialog-target="menu"">
<%= qr_code_image(url) %>
<form method="dialog" class="margin-block-start flex justify-center">
<button class="btn">
<%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Close</span>
</button>
</form>
</dialog>
</div>
<%= button_to_copy_to_clipboard(url) do %>
<%= image_tag "copy-paste.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Copy auto-login link</span>
<% end %>
<%= web_share_button(url, "Your sign-in link", "This is your own private sign-in URL, DO NOT SHARE IT. Use it to sign-in on another device or if you get locked out.") do %>
<%= image_tag "share.svg", aria: { hidden: "true" }, size: 24, class: "colorize--black" %>
<span class="for-screen-reader">Share auto-login link</span>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<div class="flex align-center gap-half pad-inline txt-medium--responsive">
<strong class="overflow-ellipsis txt-medium--responsive"><%= link_to user.name, user.current? ? edit_user_profile_path(user) : user_profile_path(user) %></strong>
<hr class="flex-item-grow margin-none" aria-hidden="true">
<%= form_with model: user, url: user_path(user), data: { controller: "form" }, method: :patch do | form | %>
<label class="btn btn--small flex-item-no-shrink" for="<%= dom_id(user, :role) %>">
<span class="for-screen-reader"><%= user.name %>'s role: <%= user.administrator? ? "Administrator" : "Member" %></span>
<%= image_tag "crown.svg", size: 24, aria: { hidden: "true" } %>
<%= form.check_box :role, { data: { action: "form#submit" }, hidden: true, id: dom_id(user, :role), disabled: ("disabled" if user.current? || !Current.user.can_administer?) }, "administrator", "member" %>
</label>
<% end %>
<%= button_to user_path(user), method: :delete, class: "btn btn--small btn--negative flex-item-no-shrink", disabled: ("disabled" if user.current? || !Current.user.can_administer?), data: {
turbo_confirm: "Are you sure you want to permanently remove this person from the account? This cant be undone."} do %>
<%= image_tag "minus.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Remove <%= user.name %> from the account</span>
<% end %>
</div>

View File

@@ -0,0 +1,35 @@
<% content_for(:title) { "People on the account" } %>
<% content_for :header do %>
<nav>
<%= link_to root_path, class: "btn" do %>
<%= image_tag "arrow-left.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Go back</span>
<% end %>
<div class="breadcrumbs">
<%= render "books/index_link" %>
<span class="flex-item-no-shrink">▸</span>
<%= image_tag "settings.svg", aria: { label: "Settings" }, size: 19, class: "colorize--black", alt: "Settings" %>
</div>
<% if Current.user.can_administer? %>
<%= link_to edit_account_custom_styles_url, class: "btn" do %>
<%= image_tag "art.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Custom styles</span>
<% end %>
<% end %>
</nav>
<% end %>
<div class="panel borderless center pad fill-shade flex flex-column margin-block">
<%= render "invite" %>
</div>
<div class="panel borderless center pad fill-none flex flex-column gap">
<%= render @users %>
</div>
<% content_for(:footer) do %>
<div class="txt-align-center center margin-block-double txt-subtle">Writebook&trade; version <%= version_badge %></div>
<% end %>

View File

@@ -0,0 +1,44 @@
<% content_for(:title) { "Create your account" } %>
<% turbo_page_requires_reload %>
<% content_for :header do %>
<nav>
<%= link_to new_session_path, class: "btn flex-item-justify-end" do %>
<%= image_tag "login-keys.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Sign in instead</span>
<% end %>
</nav>
<% end %>
<div class="panel shadow center <%= "shake" if flash[:alert] %>">
<%= image_tag "writebook-icon.svg", class: "product__logo center colorize--black", size: 130 %>
<h1 class="txt-x- large margin-none-block-start margin-block-end-double">Writebook</h1>
<%= form_with model: @user, url: join_path(params[:join_code]), class: "flex flex-column gap" do |form| %>
<div class="flex align-center gap">
<%= translation_button(:user_name) %>
<label class="flex align-center gap input input--actor">
<%= form.text_field :name, class: "input full-width", autocomplete: "name", placeholder: "Name", autofocus: true, required: true, data: { "1p-ignore": true } %>
<%= image_tag "person.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<div class="flex align-center gap">
<%= translation_button(:email_address) %>
<label class="flex align-center gap input input--actor">
<%= form.email_field :email_address, class: "input full-width", autocomplete: "username", placeholder: "Email address", required: true %>
<%= image_tag "email.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<div class="flex align-center gap">
<%= translation_button(:password) %>
<label class="flex align-center gap input input--actor">
<%= form.password_field :password, class: "input full-width", autocomplete: "new-password", placeholder: "Password", required: true, maxlength: 72 %>
<%= image_tag "password.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<button type="submit" id="log_in" class="btn btn--reversed center">
<%= image_tag "arrow-right.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Sign in</span>
</button>
<% end %>
</div>

View File

@@ -0,0 +1,63 @@
<% content_for(:title) { "Your settings" } %>
<% content_for :header do %>
<nav>
<%= link_to users_path, class: "btn" do %>
<%= image_tag "arrow-left.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Go back</span>
<% end %>
<div class="breadcrumbs">
<%= render "books/index_link" %>
<span class="flex-item-no-shrink">▸</span>
<%= link_to users_path, class: "btn borderless txt-small flex-item-no-shrink" do %>
<%= image_tag "people.svg", aria: { label: "People" }, size: 19, class: "colorize--black", alt: "People" %>
<span class="for-screen-reader">Manage people</span>
<% end %>
<span class="flex-item-no-shrink">▸</span>
<%= @user.name %>
</div>
</nav>
<% end %>
<div class="panel margin-block-double shadow center">
<%= form_with model: @user, url: user_profile_path(@user), class: "flex flex-column gap" do |form| %>
<%= form.hidden_field :role %>
<div class="flex align-center gap margin-block-start">
<%= translation_button(:user_name) %>
<label class="flex align-center gap input input--actor">
<%= form.text_field :name, class: "input full-width", autocomplete: "name", placeholder: "Name", autofocus: true, required: true, data: { "1p-ignore": true } %>
<%= image_tag "person.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<div class="flex align-center gap">
<%= translation_button(:email_address) %>
<label class="flex align-center gap input input--actor">
<%= form.email_field :email_address, class: "input full-width", autocomplete: "username", placeholder: "Email address", required: true %>
<%= image_tag "email.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<div class="flex align-center gap">
<%= translation_button(:update_password) %>
<label class="flex align-center gap input input--actor">
<%= form.password_field :password, class: "input full-width", autocomplete: "new-password", placeholder: "Change password", maxlength: 72 %>
<%= image_tag "password.svg", aria: { hidden: "true" }, size: 30, class: "colorize--black" %>
</label>
</div>
<button type="submit" class="btn btn--reversed center">
<%= image_tag "check.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Save changes</span>
</button>
<% end %>
</div>
<div class="panel margin-block-double shadow center">
<%= render "users/transfer", user: @user %>
</div>
<div class="panel margin-block-double shadow center">
<%= button_to session_path, method: :delete, class: "btn center" do %>
<%= image_tag "logout.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Sign out</span>
<% end %>
</div>

View File

@@ -0,0 +1,31 @@
<% content_for(:title) { @user.name } %>
<% content_for :header do %>
<nav>
<%= link_to users_path, class: "btn" do %>
<%= image_tag "arrow-left.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Go back</span>
<% end %>
<div class="breadcrumbs">
<%= render "books/index_link" %>
<span class="flex-item-no-shrink">▸</span>
<%= link_to users_path, class: "btn borderless txt-small flex-item-no-shrink" do %>
<%= image_tag "people.svg", aria: { label: "People" }, size: 19, class: "colorize--black", alt: "People" %>
<span class="for-screen-reader">Manage people</span>
<% end %>
<span class="flex-item-no-shrink">▸</span>
<%= @user.name %>
</div>
</nav>
<% end %>
<div class="panel margin-block-double shadow center">
<h2 class="margin-none-block-end"><%= @user.name %></h2>
<p class="margin-none-block-start"><%= mail_to @user.email_address %></p>
<% if Current.user.can_administer? %>
<hr class="full-width margin-block-double" aria-hidden="true">
<%= render "users/transfer", user: @user %>
<% end %>
</div>