mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 22:15:14 +00:00
386 lines
20 KiB
Text
386 lines
20 KiB
Text
<% content_for :title do %>
|
|
<%= @is_own_settings ? "My Settings" : "Settings | #{@user.username}" %>
|
|
<% end %>
|
|
|
|
<div class="max-w-6xl mx-auto p-6 space-y-6">
|
|
<header class="text-center mb-8">
|
|
<h1 class="text-4xl font-bold text-white mb-2">
|
|
<%= @is_own_settings ? "My Settings" : "Settings for #{@user.username}" %>
|
|
</h1>
|
|
<p class="text-muted text-lg">Change your Hackatime experience and preferences</p>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🚀</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white">Time Tracking Wizard</h2>
|
|
</div>
|
|
<p class="text-gray-300 mb-4">Get started with tracking your coding time in just a few minutes.</p>
|
|
<%= 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" %>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🌍</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_timezone">Timezone</h2>
|
|
</div>
|
|
<%= 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| %>
|
|
<div>
|
|
<%= 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: "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" } %>
|
|
</div>
|
|
<p class="text-xs text-gray-400">This affects how your activity graph and other time-based features are displayed.</p>
|
|
<%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">⚙️</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_hackatime_extension">Extension Settings</h2>
|
|
</div>
|
|
<%= 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| %>
|
|
<div>
|
|
<%= 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 { |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" } %>
|
|
</div>
|
|
<%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">💬</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_slack_status">Slack Integration</h2>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div>
|
|
<h3 class="text-lg font-medium text-white mb-2">Status Updates</h3>
|
|
<p class="text-gray-300 text-sm mb-3">When you're hacking on a project, Hackatime can update your Slack status so you can show it off!</p>
|
|
<% unless @can_enable_slack_status %>
|
|
<%= link_to "Re-authorize with Slack", slack_auth_path,
|
|
class: "inline-flex items-center gap-2 px-3 py-2 bg-gray-700 hover:bg-gray-600 text-gray-200 text-sm font-medium rounded transition-colors duration-200 mb-3" %>
|
|
<% end %>
|
|
<%= form_with model: @user,
|
|
url: @is_own_settings ? my_settings_path : settings_user_path(@user),
|
|
method: :patch, local: false do |f| %>
|
|
<div class="flex items-center gap-3">
|
|
<%= 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" %>
|
|
</div>
|
|
<%= f.submit "Save", class: "mt-3 px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="border-t border-gray-700 pt-4">
|
|
<h3 class="text-lg font-medium text-white mb-2" id="user_slack_notifications">Channel Notifications</h3>
|
|
<% if @enabled_sailors_logs.any? %>
|
|
<p class="text-gray-300 text-sm mb-2">You have notifications enabled for the following channels:</p>
|
|
<ul class="space-y-1 mb-3">
|
|
<% @enabled_sailors_logs.each do |sl| %>
|
|
<li class="text-xs text-gray-300 px-2 py-1 bg-gray-800 rounded">
|
|
<%= render "shared/slack_channel_mention", channel_id: sl.slack_channel_id %>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
<% else %>
|
|
<p class="text-gray-300 text-sm mb-3">You have no notifications enabled.</p>
|
|
<% end %>
|
|
<p class="text-xs text-gray-400">
|
|
You can enable notifications for specific channels by running <code class="px-1 py-0.5 bg-gray-800 rounded text-gray-200">/sailorslog on</code> in the Slack channel.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🔒</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_privacy">Privacy Settings</h2>
|
|
</div>
|
|
<%= 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| %>
|
|
<div class="flex items-center gap-3">
|
|
<%= 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" %>
|
|
</div>
|
|
<p class="text-xs text-gray-400">When enabled, others can view your coding statistics through public APIs.</p>
|
|
<%= f.submit "Save Settings", class: "w-full px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🏆</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_beta_features">Leaderboard Settings</h2>
|
|
</div>
|
|
<p class="text-gray-300 text-sm mb-4">Customize how you see the leaderboard</p>
|
|
<%= render "timezone_leaderboard_toggle", user: @user %>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200 md:col-span-2">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🔗</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_github_account">Connected Accounts</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="space-y-3">
|
|
<h3 class="text-lg font-medium text-white">GitHub Account</h3>
|
|
<p class="text-gray-300 text-sm">This is used to show your active projects on the leaderboard & current hacking activity on the dashboard.</p>
|
|
<% if @user.github_uid.present? %>
|
|
<div class="flex items-center gap-2 p-3 bg-gray-800 border border-gray-600 rounded">
|
|
<span class="text-green-400">✅</span>
|
|
<span class="text-gray-200 text-sm">Connected: <%= link_to "@#{@user.github_username}", "https://github.com/#{@user.github_username}", target: "_blank", class: "text-primary hover:text-primary/80 underline" %></span>
|
|
</div>
|
|
<% 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 %>
|
|
</div>
|
|
|
|
<div class="space-y-3" id="user_email_addresses">
|
|
<h3 class="text-lg font-medium text-white">Email Addresses</h3>
|
|
<p class="text-gray-300 text-sm">These are the email addresses associated with your account.</p>
|
|
<% if @user.email_addresses.any? %>
|
|
<div class="space-y-2">
|
|
<% @user.email_addresses.each do |email| %>
|
|
<div class="flex items-center gap-2 p-2 bg-gray-800 border border-gray-600 rounded">
|
|
<span class="text-gray-300 text-sm"><%= email.email %></span>
|
|
<span class="text-xs px-2 py-1 bg-gray-700 text-gray-200 rounded">
|
|
<%= email.source&.humanize || "Unknown" %>
|
|
</span>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<p class="text-gray-400 text-sm">No email addresses found.</p>
|
|
<% 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 %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">📊</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_stats_badges">Stats Badges</h2>
|
|
</div>
|
|
|
|
<div class="space-y-6">
|
|
<div>
|
|
<h3 class="text-lg font-medium text-white mb-2">General Stats Badge</h3>
|
|
<p class="text-gray-300 text-sm mb-4">Show your coding stats on your GitHub profile with beautiful badges.</p>
|
|
|
|
<div class="space-y-3">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-200 mb-2">Theme</label>
|
|
<select name="theme" id="theme-select" onchange="up1(this.value)"
|
|
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">
|
|
<% GithubReadmeStats.themes.each do |theme| %>
|
|
<option value="<%= theme %>"><%= theme.humanize %></option>
|
|
<% end %>
|
|
</select>
|
|
</div>
|
|
|
|
<% gh_badge = GithubReadmeStats.new(current_user.id, "darcula") %>
|
|
<div class="p-4 bg-gray-800 border border-gray-600 rounded">
|
|
<img id="badge-preview" src="<%= gh_badge.generate_badge_url %>" data-url="<%= gh_badge.generate_badge_url %>" class="mb-3 rounded">
|
|
<pre id="badge-url" class="text-xs text-gray-300 bg-gray-900 p-2 rounded overflow-x-auto"><%= gh_badge.generate_badge_url %></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% if @projects.any? && @user.slack_uid.present? %>
|
|
<div class="border-t border-gray-700 pt-4">
|
|
<h3 class="text-lg font-medium text-white mb-2">Project Stats Badge</h3>
|
|
<div class="space-y-2">
|
|
<label class="block text-sm font-medium text-gray-200">Project</label>
|
|
<select name="project" id="project-select" onchange="up2(this.value)"
|
|
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">
|
|
<% @projects.each do |project| %>
|
|
<option value="<%= project %>"><%= project %></option>
|
|
<% end %>
|
|
</select>
|
|
<div class="mt-3 p-4 bg-gray-800 border border-gray-600 rounded">
|
|
<img id="project-badge-preview" src="<%= @work_time_stats_url %>" class="mb-3 rounded">
|
|
<pre id="project-badge-url" class="text-xs text-gray-300 bg-gray-900 p-2 rounded overflow-x-auto"><%= @work_time_stats_url %></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<script>
|
|
function up1(theme) {
|
|
const preview = document.getElementById('badge-preview');
|
|
const url = document.getElementById('badge-url');
|
|
const baseUrl = preview.dataset.url.replace(/theme=[^&]*/, '');
|
|
const newUrl = baseUrl + (baseUrl.includes('?') ? '&' : '?') + 'theme=' + theme;
|
|
preview.src = newUrl;
|
|
url.textContent = newUrl;
|
|
}
|
|
|
|
function up2(project) {
|
|
const preview = document.getElementById('project-badge-preview');
|
|
const url = document.getElementById('project-badge-url');
|
|
const baseUrl = '<%= @work_time_stats_url.gsub(@projects.first || 'example', '') %>';
|
|
const newUrl = baseUrl + project;
|
|
preview.src = newUrl;
|
|
url.textContent = newUrl;
|
|
}
|
|
</script>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200 space-y-6">
|
|
<div>
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">📄</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_config_file">Config File</h2>
|
|
</div>
|
|
<p class="text-gray-300 text-sm mb-4">Your Wakatime configuration file for tracking coding time.</p>
|
|
|
|
<div class="bg-gray-800 border border-gray-600 rounded p-4 overflow-x-auto">
|
|
<%= render "wakatime_config_display" %>
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-2">
|
|
This configuration file is automatically generated and updated when you make changes to your settings.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="border-t border-gray-700 pt-6">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🚚</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_migration_assistant">Migration Assistant</h2>
|
|
</div>
|
|
<p class="text-gray-300 text-sm mb-4">This will migrate your heartbeats from waka.hackclub.com to this platform.</p>
|
|
|
|
<%= 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? %>
|
|
<div class="mt-4 space-y-2">
|
|
<h3 class="text-sm font-medium text-white">Migration Status</h3>
|
|
<% @heartbeats_migration_jobs.each do |job| %>
|
|
<div class="p-2 bg-gray-800 border border-gray-600 rounded text-xs text-gray-300">
|
|
Job ID: <%= job.id %> - Status: <%= job.status %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 hover:bg-gray-800/50 transition-all duration-200 md:col-span-2">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">📝</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white" id="user_markscribe">Markscribe Templates</h2>
|
|
</div>
|
|
<p class="text-gray-300 text-sm mb-4">Use markscribe to create beautiful GitHub profile READMEs with your coding stats.</p>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<div>
|
|
<div class="p-4 bg-gray-800 border border-gray-600 rounded mb-4 overflow-x-auto">
|
|
<pre class="text-sm text-gray-200 whitespace-pre-wrap break-all"><code>{{ wakatimeDoubleCategoryBar "💾 Languages:" wakatimeData.Languages "💼 Projects:" wakatimeData.Projects 5 }}</code></pre>
|
|
</div>
|
|
<p class="text-gray-300 text-sm mb-2">Add this to your GitHub profile README template to display your top languages and projects.</p>
|
|
<p class="text-xs text-gray-400">See the <a href="https://github.com/taciturnaxolotl/markscribe#your-wakatime-languages-formated-as-a-bar" target="_blank" class="text-primary hover:text-primary/80 underline">markscribe documentation</a> for more template options.</p>
|
|
</div>
|
|
<div>
|
|
<img src="https://cdn.fluff.pw/slackcdn/524e293aa09bc5f9115c0c29c18fb4bc.png"
|
|
alt="Example of markscribe output showing coding language and project statistics"
|
|
class="w-full rounded border border-gray-600"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% admin_tool do %>
|
|
<div class="p-6 md:col-span-2">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-red-600/10 rounded">
|
|
<span class="text-2xl">🔧</span>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-white">WakaTime Mirrors</h2>
|
|
</div>
|
|
|
|
<% if current_user.wakatime_mirrors.any? %>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
<% current_user.wakatime_mirrors.each do |mirror| %>
|
|
<div class="p-4 bg-gray-800 border border-gray-600 rounded">
|
|
<h3 class="text-white font-medium"><%= mirror.name %></h3>
|
|
<p class="text-gray-400 text-sm"><%= mirror.endpoint_url %></p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
|
|
<%= form_with(model: [current_user, WakatimeMirror.new], local: true, class: "space-y-4") do |f| %>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<%= 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" %>
|
|
</div>
|
|
<div>
|
|
<%= 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" %>
|
|
</div>
|
|
</div>
|
|
<%= f.submit "Add Mirror", class: "px-4 py-2 bg-primary text-white font-medium rounded transition-colors duration-200" %>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|