Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/zip_liner/accounts/member.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule ZipLiner.Accounts.Member do

@roles ~w(student alumni instructor staff mentor guest)a
@statuses ~w(active suspended deprovisioned)a
@theme_preferences ~w(light dark)a
@admin_handles ~w(kristofer)

schema "members" do
Expand All @@ -21,6 +22,7 @@ defmodule ZipLiner.Accounts.Member do
field :status, Ecto.Enum, values: @statuses, default: :active
field :is_admin, :boolean, default: false
field :open_to_opportunities, :boolean, default: false
field :theme_preference, Ecto.Enum, values: @theme_preferences, default: :light
field :skills, {:array, :string}, default: []
field :avatar_source, Ecto.Enum, values: [:github, :linkedin], default: :github

Expand Down Expand Up @@ -57,6 +59,7 @@ defmodule ZipLiner.Accounts.Member do
:role,
:status,
:open_to_opportunities,
:theme_preference,
:skills,
:avatar_source,
:cohort_id
Expand Down
2 changes: 1 addition & 1 deletion lib/zip_liner_web/components/layouts/root.html.heex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-bs-theme={if(assigns[:current_member] && assigns[:current_member].theme_preference == :dark, do: "dark", else: "light")}>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down
17 changes: 17 additions & 0 deletions lib/zip_liner_web/controllers/settings_html/edit.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@
</div>
</div>

<div class="col-12">
<h2 class="h5 fw-semibold mb-3">Theme</h2>
<input type="hidden" name="member[theme_preference]" value="light" />
<div class="form-check form-switch">
<input
type="checkbox"
id="member_theme_preference"
name="member[theme_preference]"
value="dark"
checked={@member.theme_preference == :dark}
class="form-check-input"
role="switch"
/>
<label for="member_theme_preference" class="form-check-label">Use dark mode</label>
</div>
</div>

<div class="col-12">
<button type="submit" class="btn btn-primary">Save Settings</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ZipLiner.Repo.Migrations.AddThemePreferenceToMembers do
use Ecto.Migration

def change do
alter table(:members) do
add :theme_preference, :string, default: "light", null: false
end
end
end
6 changes: 6 additions & 0 deletions test/zip_liner/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ defmodule ZipLiner.AccountsTest do
assert updated.bio == "Hello world"
end

test "update_member/2 updates theme_preference" do
member = member_fixture()
{:ok, updated} = Accounts.update_member(member, %{theme_preference: :dark})
assert updated.theme_preference == :dark
end

test "update_member/2 saves a valid linkedin_url" do
member = member_fixture()
{:ok, updated} = Accounts.update_member(member, %{linkedin_url: "https://www.linkedin.com/in/testuser"})
Expand Down
29 changes: 29 additions & 0 deletions test/zip_liner_web/controllers/settings_controller_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule ZipLinerWeb.SettingsControllerTest do
use ZipLinerWeb.ConnCase

alias ZipLiner.Accounts

describe "settings" do
setup :log_in_member

test "edit renders theme switch with light mode default", %{conn: conn} do
conn = get(conn, ~p"/settings")
html = html_response(conn, 200)

assert html =~ "Use dark mode"
assert html =~ ~s(name="member[theme_preference]")
assert html =~ ~s(data-bs-theme="light")
end

test "update persists dark mode preference", %{conn: conn, member: member} do
conn = put(conn, ~p"/settings", member: %{"theme_preference" => "dark"})
assert redirected_to(conn) == ~p"/settings"

updated_member = Accounts.get_member!(member.id)
assert updated_member.theme_preference == :dark

conn = get(recycle(conn), ~p"/settings")
assert html_response(conn, 200) =~ ~s(data-bs-theme="dark")
end
end
end