diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 06871fa..7471403 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -10,7 +10,6 @@ */ @import "https://uchu.style/color.css"; -@import "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"; @import "settings.css"; /* Force dark mode for all elements */ diff --git a/app/assets/stylesheets/settings.css b/app/assets/stylesheets/settings.css deleted file mode 100644 index 387971a..0000000 --- a/app/assets/stylesheets/settings.css +++ /dev/null @@ -1,160 +0,0 @@ -.settings-page .grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr)); - gap: 1rem; - margin-top: 2rem; -} - -.settings-page article { - background: var(--pico-card-background-color); - border: var(--pico-border-width) solid var(--pico-card-border-color); - border-radius: var(--pico-border-radius); - box-shadow: var(--pico-card-box-shadow); - transition: box-shadow var(--pico-transition); - margin: 0; -} - -.settings-page article header { - padding: 0.5rem; - border-bottom: 1px solid var(--pico-muted-border-color); -} - -.settings-page article header h2 { - margin-bottom: 0; - font-size: 1.25rem; - font-weight: 600; - color: var(--pico-color); -} - -.settings-page article header p { - margin-bottom: 0; - color: var(--pico-muted-color); - font-size: 0.875rem; -} - -.settings-page article section { - margin-top: 1.5rem; - padding-top: 1rem; - border-top: 1px solid var(--pico-muted-border-color); -} - -.settings-page article section:first-of-type { - margin-top: 0; - padding-top: 0; - border-top: none; -} - -.settings-page article section h3 { - margin-bottom: 0.75rem; - font-size: 1rem; - font-weight: 500; - color: var(--pico-color); -} - -.settings-page article .form-group { - margin-bottom: 1rem; -} - -.settings-page article .form-group:last-child { - margin-bottom: 0; -} - -.settings-page article button[role="button"], -.settings-page article input[type="submit"][role="button"] { - margin-top: 1rem; -} - -.settings-page article .secondary { - background-color: var(--pico-secondary-background); - border-color: var(--pico-secondary-border); - color: var(--pico-secondary-color); -} - -.settings-page article .secondary:hover { - background-color: var(--pico-secondary-hover-background); - border-color: var(--pico-secondary-hover-border); -} - -.settings-page article .code-example { - margin: 1rem 0; - background: var(--pico-code-background-color); - border-radius: var(--pico-border-radius); -} - -.settings-page article .code-example pre { - margin: 0; - background: transparent; - padding: 0; -} - -.settings-page article img { - max-width: 100%; - height: auto; - margin: 1rem 0; - border-radius: var(--pico-border-radius); -} - -.settings-page article pre:not(.code-example pre) { - background: var(--pico-code-background-color); - padding: 0.75rem; - border-radius: var(--pico-border-radius); - font-size: 0.875rem; - overflow-x: auto; -} - -.settings-page .mirror { - padding: 1rem; - background: var(--pico-card-sectioning-background-color); - border-radius: var(--pico-border-radius); - margin-bottom: 1rem; -} - -.settings-page .mirror:last-child { - margin-bottom: 0; -} - -.settings-page .email-form { - margin-top: 1rem; - padding-top: 1rem; - border-top: 1px solid var(--pico-muted-border-color); -} - -.settings-page .email-form .field { - display: flex; - gap: 0.5rem; - align-items: end; -} - -.settings-page .email-form input[type="email"] { - flex: 1; - margin-bottom: 0; -} - -@media (max-width: 768px) { - .settings-page .grid { - grid-template-columns: 1fr; - gap: 1.5rem; - } - - .settings-page article { - padding: 1rem; - } - - .settings-page .email-form .field { - flex-direction: column; - align-items: stretch; - } -} - -/* Dark mode styles (now default) */ -.settings-page article { - background: var(--pico-card-background-color, #1e293b); - border-color: var(--pico-card-border-color, #334155); -} - -.settings-page article:hover { - box-shadow: var( - --pico-card-box-shadow-hover, - 0 0.125rem 1rem rgba(0, 0, 0, 0.3) - ); -} diff --git a/app/views/users/_timezone_leaderboard_toggle.html.erb b/app/views/users/_timezone_leaderboard_toggle.html.erb index 898e929..a6572b9 100644 --- a/app/views/users/_timezone_leaderboard_toggle.html.erb +++ b/app/views/users/_timezone_leaderboard_toggle.html.erb @@ -1,11 +1,13 @@ -
-

- Regional & Timezone Leaderboards
- Access regional leaderboards that show users in your timezone region or specific timezone. Choose between timezone-specific, regional (UTC offset), or global competition modes. -

- <%= form_with model: user, url: (@is_own_settings ? my_settings_path : settings_user_path(user)), method: :patch, local: false do |f| %> - <%= f.check_box :default_timezone_leaderboard, checked: user.default_timezone_leaderboard, id: "user_default_timezone_leaderboard" %> - <%= f.label :default_timezone_leaderboard, "Default to Timezone Leaderboard", for: "user_default_timezone_leaderboard" %> - <%= f.submit "Save", role: "button" %> - <% end %> -
+<%= form_with model: user, url: (@is_own_settings ? my_settings_path : settings_user_path(user)), method: :patch, local: false, class: "space-y-4" do |f| %> +
+ <%= f.check_box :default_timezone_leaderboard, + checked: user.default_timezone_leaderboard, + id: "user_default_timezone_leaderboard", + class: "w-4 h-4 text-primary border-gray-600 rounded focus:ring-primary bg-gray-800" %> + <%= f.label :default_timezone_leaderboard, "Default to Timezone Leaderboard", + for: "user_default_timezone_leaderboard", + class: "text-sm text-gray-200" %> +
+

Access regional leaderboards that show users in your timezone region or specific timezone. Choose between timezone-specific, regional (UTC offset), or global competition modes.

+ <%= f.submit "Save", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded-lg transition-colors duration-200" %> +<% end %> diff --git a/app/views/users/_wakatime_config_display.html.erb b/app/views/users/_wakatime_config_display.html.erb index e2f6d42..6797825 100644 --- a/app/views/users/_wakatime_config_display.html.erb +++ b/app/views/users/_wakatime_config_display.html.erb @@ -1,5 +1,5 @@ <% if @user.api_keys.any? %> -
+  
 # put this in your ~/.wakatime.cfg file
 
 [settings]
@@ -7,10 +7,9 @@ api_url = https://<%= request.host_with_port %>/api/hackatime/v1
 api_key = <%= @user.api_keys.last.token %>
 heartbeat_rate_limit_seconds = 30
 
-# any other wakatime configs you want to add: https://github.com/wakatime/wakatime-cli/blob/develop/USAGE.md#ini-config-file
-  
+# any other wakatime configs you want to add: https://github.com/wakatime/wakatime-cli/blob/develop/USAGE.md#ini-config-file
<% else %>

- No API keys found. Please migrate your keys from waka.hackclub.com below. New API key generation has yet to be implemented. +No API keys found. Please migrate your keys from waka.hackclub.com below. New API key generation has yet to be implemented.

<% end %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index b3a2dd4..9de3072 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -2,358 +2,385 @@ <%= @is_own_settings ? "My Settings" : "Settings | #{@user.username}" %> <% end %> -<% content_for :body_class, "settings-page" %> - -
-
-

<%= @is_own_settings ? "My Settings" : "Settings for #{@user.username}" %>

-

Change your settings for Hackatime and Sailors Log.

+
+
+

+ <%= @is_own_settings ? "My Settings" : "Settings for #{@user.username}" %> +

+

Change your Hackatime experience and preferences

-
+
+
+
+
+ ๐Ÿš€ +
+

Time Tracking Wizard

+
+

Get started with tracking your coding time in just a few minutes.

+ <%= link_to "Set up time tracking", my_wakatime_setup_path, + class: "inline-flex items-center gap-2 px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> +
-
-
-

๐Ÿš€ Time tracking wizard

-
-

Get started with tracking your coding time in just a few minutes.

- <%= link_to "Set up time tracking", my_wakatime_setup_path, role: "button" %> -
- -
-
-

๐ŸŒ Timezone

-
+
+
+
+ ๐ŸŒ +
+

Timezone

+
<%= form_with model: @user, url: @is_own_settings ? my_settings_path : settings_user_path(@user), - method: :patch do |f| %> -
- <%= f.label :timezone, "Your timezone" %> - <%= f.select :timezone, + method: :patch, local: false, + class: "space-y-4" do |f| %> +
+ <%= f.label :timezone, "Your timezone", class: "block text-sm font-medium text-gray-200 mb-2" %> + <%= f.select :timezone, TZInfo::Timezone.all.map(&:identifier).sort, - include_blank: @user.timezone.blank?, class: "form-select" %> + { include_blank: @user.timezone.blank? }, + { class: "w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary" } %>
- This affects how your activity graph and other time-based features are displayed. - <%= f.submit "Save Settings", role: "button" %> +

This affects how your activity graph and other time-based features are displayed.

+ <%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> <% end %> -
+
-
-
-

๐Ÿ’ฌ Slack Integration

-
- -
-

Status Updates

-

When you're hacking on a project, Hackatime can update your Slack status so you can show it off!

- <% unless @can_enable_slack_status %> - <%= link_to "Re-authorize with Slack to give permission to update your status", slack_auth_path, role: "button", class: "secondary" %> - <% end %> - <%= form_with model: @user, - url: @is_own_settings ? my_settings_path : settings_user_path(@user), - method: :patch do |f| %> -
- -
- <%= f.submit "Save Settings", role: "button" %> - <% end %> -
- -
-

Channel Notifications

- <% if @enabled_sailors_logs.any? %> -

You have notifications enabled for the following channels:

-
    - <% @enabled_sailors_logs.each do |sl| %> -
  • - <%= render "shared/slack_channel_mention", channel_id: sl.slack_channel_id %> -
  • - <% end %> -
- <% else %> -

You have no notifications enabled.

- <% end %> -

- You can enable notifications for specific channels by running /sailorslog on in the Slack channel you want to enable notifications for. -

-
-
- -
-
-

๐Ÿ”— Connected Accounts

-
- -
-

GitHub Account

-

This is used to show your active projects on the leaderboard & current hacking activity on the dashboard.

- <% if @user.github_uid.present? %> -

โœ… Your GitHub account is linked: <%= link_to "@#{@user.github_username}", "https://github.com/#{@user.github_username}", target: "_blank" %>

- <% if @user.github_access_token.present? %> - <%= link_to "Relink GitHub Account", github_auth_path, data: { turbo: "false" }, role: "button" %> - <%= link_to "Unlink GitHub Account", github_unlink_path, - data: { - turbo_method: :delete, - confirm: "Are you sure? This will remove access to your GitHub data." - }, - role: "button", - class: "outline" %> - <% else %> -

โš ๏ธ Your GitHub token has expired. Please relink your account.

- <%= link_to "Relink GitHub Account", github_auth_path, data: { turbo: "false" }, role: "button" %> - <% end %> - <% else %> - <%= link_to "Link GitHub Account", github_auth_path, data: { turbo: "false" }, role: "button" %> - <% end %> -
- -
-

Email Addresses

-

These are the email addresses associated with your account.

- <% if @user.email_addresses.any? %> -
    - <% @user.email_addresses.each do |email_address| %> -
  • - <%= email_address.email %> - <% if email_address.source.present? %> - - (from <%= email_address.source.humanize %>) - - <% end %> -
  • - <% end %> -
- <% else %> -

No email addresses found.

- <% end %> - -
-
- -
-
-

โš™๏ธ Extension Settings

-
+

Extension Settings

+
<%= form_with model: @user, url: @is_own_settings ? my_settings_path : settings_user_path(@user), - method: :patch do |f| %> -
- <%= f.label "Simple text" %> + method: :patch, local: false, + class: "space-y-4" do |f| %> +
+ <%= f.label :hackatime_extension_text_type, "Status bar text style", class: "block text-sm font-medium text-gray-200 mb-2" %> <%= f.select :hackatime_extension_text_type, - User.hackatime_extension_text_types.keys.map { |type| [type.humanize, type] }, - selected: @user.hackatime_extension_text_type, class: "form-select" %> + User.hackatime_extension_text_types.keys.map { |key| [key.humanize, key] }, + {}, + { class: "w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary" } %>
- <%= f.submit "Save Settings", role: "button" %> + <%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> <% end %> - +
-
-
-

๐Ÿ“Š Stats Badges

-
-
-

Show your coding stats on your GitHub profile with beautiful badges.

-

General Stats Badge

-

This badge shows your overall coding statistics.

- - <% gh_badge = GithubReadmeStats.new(current_user.id, "darcula") %> - -
<%= gh_badge.generate_badge_url %>
-
+ <%= form_with model: @user, + url: @is_own_settings ? my_settings_path : settings_user_path(@user), + method: :patch, local: false do |f| %> +
+ <%= f.check_box :uses_slack_status, + class: "w-4 h-4 text-primary border-gray-600 rounded focus:ring-primary bg-gray-800" %> + <%= f.label :uses_slack_status, "Update my Slack status automatically", + class: "text-sm text-gray-200" %> +
+ <%= f.submit "Save", class: "mt-3 px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> + <% end %> +
- <% if @projects.any? && @user.slack_uid.present? %> -
-

Project Stats Badge

-

This badge shows individual project statistics.

-

See the documentation for more customization options!

- - -
<%= @work_time_stats_url %>
-
+
+

Channel Notifications

+ <% if @enabled_sailors_logs.any? %> +

You have notifications enabled for the following channels:

+
    + <% @enabled_sailors_logs.each do |sl| %> +
  • + <%= render "shared/slack_channel_mention", channel_id: sl.slack_channel_id %> +
  • + <% end %> +
+ <% else %> +

You have no notifications enabled.

+ <% end %> +

+ You can enable notifications for specific channels by running /sailorslog on in the Slack channel. +

+
+ + + +
+
+
+ ๐Ÿ”’ +
+

Privacy Settings

+
+ <%= form_with model: @user, + url: @is_own_settings ? my_settings_path : settings_user_path(@user), + method: :patch, local: false, + class: "space-y-4" do |f| %> +
+ <%= f.check_box :allow_public_stats_lookup, + class: "w-4 h-4 text-primary border-gray-600 rounded focus:ring-primary bg-gray-800" %> + <%= f.label :allow_public_stats_lookup, "Allow public stats lookup", + class: "text-sm text-gray-200" %> +
+

When enabled, others can view your coding statistics through public APIs.

+ <%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> <% end %> +
+ +
+
+
+ ๐Ÿ† +
+

Leaderboard Settings

+
+

Customize how you see the leaderboard

+ <%= render "timezone_leaderboard_toggle", user: @user %> +
+ +
+
+
+ ๐Ÿ”— +
+

Connected Accounts

+
+ +
+
+

GitHub Account

+

This is used to show your active projects on the leaderboard & current hacking activity on the dashboard.

+ <% if @user.github_uid.present? %> +
+ โœ… + Connected: <%= link_to "@#{@user.github_username}", "https://github.com/#{@user.github_username}", target: "_blank", class: "text-primary hover:text-primary/80 underline" %> +
+ <% unless @user.github_access_token.present? %> + <%= link_to "Relink GitHub Account", github_auth_path, data: { turbo: "false" }, + class: "inline-flex items-center gap-2 px-3 py-2 bg-primary text-white text-sm font-medium rounded transition-colors duration-200" %> + <% end %> + <% else %> + <%= link_to "Link GitHub Account", github_auth_path, data: { turbo: "false" }, + class: "inline-flex items-center gap-2 px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> + <% end %> +
+ +
+

Email Addresses

+

These are the email addresses associated with your account.

+ <% if @user.email_addresses.any? %> +
+ <% @user.email_addresses.each do |email| %> +
+ <%= email.email %> + + <%= email.source&.humanize || "Unknown" %> + +
+ <% end %> +
+ <% else %> +

No email addresses found.

+ <% end %> + <%= form_tag add_email_auth_path, data: { turbo: false }, class: "space-y-2" do %> + <%= email_field_tag :email, nil, + placeholder: "Add another email address", + required: true, + class: "w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary text-sm" %> + <%= submit_tag "Add Email", class: "w-full px-3 py-2 bg-primary hover:bg-primary/80 text-white text-sm font-medium rounded transition-colors duration-200" %> + <% end %> +
+
+
+ +
+
+
+ ๐Ÿ“Š +
+

Stats Badges

+
+ +
+
+

General Stats Badge

+

Show your coding stats on your GitHub profile with beautiful badges.

+ +
+
+ + +
+ + <% gh_badge = GithubReadmeStats.new(current_user.id, "darcula") %> +
+ +
<%= gh_badge.generate_badge_url %>
+
+
+
+ + <% if @projects.any? && @user.slack_uid.present? %> +
+

Project Stats Badge

+
+ + +
+ +
<%= @work_time_stats_url %>
+
+
+
+ <% end %> +
- +
-
-
-

๐Ÿ“ Markscribe Templates

-

Use markscribe to create beautiful GitHub profile READMEs with your coding stats.

-
- -
-
{{ wakatimeDoubleCategoryBar "๐Ÿ’พ Languages:" wakatimeData.Languages "๐Ÿ’ผ Projects:" wakatimeData.Projects 5 }}
-
-

Add this to your GitHub profile README template to display your top languages and projects.

-

See the markscribe documentation for more template options.

- Example of markscribe output showing coding language and project statistics -
- -
-
-

๐Ÿ“„ Config File

-

- <% if current_user.most_recent_direct_entry_heartbeat %> - Your last heartbeat was <%= time_ago_in_words current_user.most_recent_direct_entry_heartbeat.created_at %> ago. - <% else %> - You haven't sent any heartbeats yet directly to this platform. - <% end %> +

+
+
+
+ ๐Ÿ“„ +
+

Config File

+
+

Your Wakatime configuration file for tracking coding time.

+ +
+ <%= render "wakatime_config_display" %> +
+

+ This configuration file is automatically generated and updated when you make changes to your settings.

-
+ + +
+
+
+ ๐Ÿšš +
+

Migration Assistant

+
+

This will migrate your heartbeats from waka.hackclub.com to this platform.

+ + <%= button_to "Migrate heartbeats", my_settings_migrate_heartbeats_path, method: :post, + class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> + + <% if @heartbeats_migration_jobs.any? %> +
+

Migration Status

+ <% @heartbeats_migration_jobs.each do |job| %> +
+ Job ID: <%= job.id %> - Status: <%= job.status %> +
+ <% end %> +
+ <% end %> +
+ + +
+
+
+ ๐Ÿ“ +
+

Markscribe Templates

+
+

Use markscribe to create beautiful GitHub profile READMEs with your coding stats.

- <%= render "wakatime_config_display" %> -

- - This file is located in ~/.wakatime.cfg on your computer. - You can configure it with other settings as well. - -

-
- -
-
-

๐Ÿ”’ Privacy Settings

-
- - <%= form_with model: @user, - url: @is_own_settings ? my_settings_path : settings_user_path(@user), - method: :patch do |f| %> -
- -
- <%= f.submit "Save Settings", role: "button" %> - <% end %> -
- -
-
-

๐Ÿ† Leaderboard settings

-

Customize how you see the leaderboard

-
- <%= render "timezone_leaderboard_toggle", user: @user %> -
- - <%# -
-
-

๐Ÿงช Beta Features

-

Enable experimental features and help us test new functionality.

-
-
- %> +
+
+
+
{{ wakatimeDoubleCategoryBar "๐Ÿ’พ Languages:" wakatimeData.Languages "๐Ÿ’ผ Projects:" wakatimeData.Projects 5 }}
+
+

Add this to your GitHub profile README template to display your top languages and projects.

+

See the markscribe documentation for more template options.

+
+
+ Example of markscribe output showing coding language and project statistics +
+
+ <% admin_tool do %> -
-
-

๐Ÿ”„ WakaTime Mirror

-

Mirror your coding activity to WakaTime.

-
- +
+
+
+ ๐Ÿ”ง +
+

WakaTime Mirrors

+
+ <% if current_user.wakatime_mirrors.any? %> -
+
<% current_user.wakatime_mirrors.each do |mirror| %> -
-

- Endpoint: <%= mirror.endpoint_url %>
- Last synced: <%= mirror.last_synced_at ? time_ago_in_words(mirror.last_synced_at) + " ago" : "Never" %> -

- <%= button_to "Delete", user_wakatime_mirror_path(current_user, mirror), method: :delete, role: "button", class: "secondary", data: { confirm: "Are you sure?" } %> +
+

<%= mirror.name %>

+

<%= mirror.endpoint_url %>

<% end %>
<% end %> - <%= form_with(model: [current_user, WakatimeMirror.new], local: true) do |f| %> -
- <%= f.label :endpoint_url, "WakaTime API Endpoint" %> - <%= f.text_field :endpoint_url, value: "https://wakatime.com/api/v1", placeholder: "https://wakatime.com/api/v1", class: "form-control" %> + <%= form_with(model: [current_user, WakatimeMirror.new], local: true, class: "space-y-4") do |f| %> +
+
+ <%= f.label :name, class: "block text-sm font-medium text-gray-200 mb-2" %> + <%= f.text_field :name, class: "w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary" %> +
+
+ <%= f.label :endpoint_url, class: "block text-sm font-medium text-gray-200 mb-2" %> + <%= f.url_field :endpoint_url, class: "w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white focus:border-primary focus:ring-1 focus:ring-primary" %> +
- -
- <%= f.label :encrypted_api_key, "WakaTime API Key" %> - <%= f.text_field :encrypted_api_key, placeholder: "Enter your WakaTime API key", class: "form-control" %> -
- <%= f.submit "Add Mirror", role: "button" %> + <%= f.submit "Add Mirror", class: "px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %> <% end %> -
+ <% end %> - -
-
-

๐Ÿšš Migration Assistant

-

This will migrate your heartbeats from waka.hackclub.com to this platform.

-
- - <%= button_to "Migrate heartbeats", my_settings_migrate_heartbeats_path, method: :post, role: "button" %> - - <% if @heartbeats_migration_jobs.any? %> -
-

Migration Jobs

-
    - <% @heartbeats_migration_jobs.each do |job| %> -
  • - <% if job.finished_at && !job.error %> - โœ… - <% elsif job.finished_at && job.error %> - โŒ - <% else %> - โณ - <% end %> - Job started at <%= job.created_at.strftime("%Y-%m-%d %H:%M:%S") %> - <% if job.finished_at %> - (and finished after <%= distance_of_time_in_words(job.finished_at - job.created_at) %>) - <% end %> - <% admin_tool('', 'span') do %> - <%= link_to "View job", GoodJob::Engine.routes.url_helpers.job_path(job.id) %> - <% end %> -
  • - <% end %> -
-
- <% end %> -
-
+