From 9853da0fd16d61bf1431d992e5926704a24d6d08 Mon Sep 17 00:00:00 2001 From: Mahad Kalam Date: Wed, 25 Feb 2026 10:22:15 +0000 Subject: [PATCH 1/7] Add OS switcher tabs to WakatimeSetup page - Add segmented control with macOS/Linux/Codespaces, Windows, and Advanced tabs - Default tab is auto-detected from user agent (server-side) - Show WSL option in mac/linux tab label only when user is on Windows - Use modal-matching cubic-bezier easing for tab transitions --- .../pages/WakatimeSetup/Index.svelte | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/app/javascript/pages/WakatimeSetup/Index.svelte b/app/javascript/pages/WakatimeSetup/Index.svelte index cab6c6a4..7a19c681 100644 --- a/app/javascript/pages/WakatimeSetup/Index.svelte +++ b/app/javascript/pages/WakatimeSetup/Index.svelte @@ -14,9 +14,8 @@ let { current_user_api_key, setup_os, api_url, heartbeat_check_url }: Props = $props(); - let activeSection = $derived( - setup_os === "windows" ? "windows" : "mac-linux", - ); + let activeSection = $state(setup_os === "windows" ? "windows" : "mac-linux"); + let isWindows = setup_os === "windows"; let hasHeartbeat = $state(false); let heartbeatTimeAgo = $state(""); let checkCount = $state(0); @@ -37,10 +36,6 @@ const sharedSubtitle = "This creates your config file and validates your API key. And if you're using VS Code, a JetBrains IDE, Zed, or Xcode, we'll even set up the plugins for you!"; - function toggleSection(section: string) { - activeSection = section; - } - function showSuccess(timeAgo: string) { hasHeartbeat = true; heartbeatTimeAgo = timeAgo; @@ -126,6 +121,36 @@ {/if} +
+ + + +
+ {#if activeSection === "mac-linux"}
From 7e99e8a8d788ef6770cf36c51eac5338b50d49b8 Mon Sep 17 00:00:00 2001 From: Mahad Kalam Date: Wed, 25 Feb 2026 10:25:13 +0000 Subject: [PATCH 2/7] Add system test for WakatimeSetup OS switcher tabs --- test/system/wakatime_setup_test.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/system/wakatime_setup_test.rb diff --git a/test/system/wakatime_setup_test.rb b/test/system/wakatime_setup_test.rb new file mode 100644 index 00000000..2fe64d1f --- /dev/null +++ b/test/system/wakatime_setup_test.rb @@ -0,0 +1,30 @@ +require "application_system_test_case" + +class WakatimeSetupTest < ApplicationSystemTestCase + setup do + @user = User.create!(timezone: "UTC") + sign_in_as(@user) + end + + test "shows OS switcher tabs and can switch between them" do + visit my_wakatime_setup_path + + # Default tab should be macOS / Linux / Codespaces (non-Windows user agent) + assert_text "Configure Hackatime" + assert_text "curl -fsSL" + + # Switch to Windows tab + click_on "Windows" + assert_text "Open PowerShell" + assert_text "install.ps1" + + # Switch to Advanced tab + click_on "Advanced" + assert_text "~/.wakatime.cfg" + assert_text "api_url" + + # Switch back to macOS / Linux tab + click_on "macOS / Linux" + assert_text "curl -fsSL" + end +end From 372917c9b3bc15244a3a05881bd357c59763fee9 Mon Sep 17 00:00:00 2001 From: Mahad Kalam Date: Wed, 25 Feb 2026 10:32:58 +0000 Subject: [PATCH 3/7] Extract repeated tab classes into tabClass helper --- .../pages/WakatimeSetup/Index.svelte | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/javascript/pages/WakatimeSetup/Index.svelte b/app/javascript/pages/WakatimeSetup/Index.svelte index 7a19c681..1768705d 100644 --- a/app/javascript/pages/WakatimeSetup/Index.svelte +++ b/app/javascript/pages/WakatimeSetup/Index.svelte @@ -16,6 +16,15 @@ let activeSection = $state(setup_os === "windows" ? "windows" : "mac-linux"); let isWindows = setup_os === "windows"; + + const tabBase = + "flex-1 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]"; + const tabActive = "bg-darkless text-surface-content shadow-sm"; + const tabInactive = "text-secondary hover:text-surface-content"; + function tabClass(section: string) { + return `${tabBase} ${activeSection === section ? tabActive : tabInactive}`; + } + let hasHeartbeat = $state(false); let heartbeatTimeAgo = $state(""); let checkCount = $state(0); @@ -123,28 +132,19 @@