hackatime/app/views/static_pages/index.html.erb
2026-02-02 11:20:35 -05:00

235 lines
19 KiB
Text

<div class="container">
<% if current_user&.trust_level == "red" %>
<div class="text-primary bg-red-500/10 border-2 border-red-500/20 p-4 text-center rounded-lg mb-4">
<div class="flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M8 14.5a6.5 6.5 0 1 0 0-13a6.5 6.5 0 0 0 0 13M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m1-5a1 1 0 1 1-2 0a1 1 0 0 1 2 0m-.25-6.25a.75.75 0 0 0-1.5 0v3.5a.75.75 0 0 0 1.5 0z" clip-rule="evenodd" /></svg>
<span class="text-3xl font-bold block ml-2">Hold up! Your account has been banned for suspicious activity.</span>
</div>
<div>
<p class="text-primary text-left text-lg mb-2"><b>What does this mean?</b> Your account was convicted for fraud or abuse of Hackatime, such as using methods to gain an unfair advantage on the leaderboards or attempting to manipulate your coding time in any way. This restricts your access to participate in public leaderboards, but Hackatime will still track and display your time. This may also affect your ability to participate in current and future Hack Club events.</p>
<p class="text-primary text-left text-lg mb-2"><b>What can I do?</b> Account bans are non-negotiable, and will not be removed unless determined to have been issued incorrectly. In that case, it will automatically be removed. We take fraud very seriously and have a zero-tolerance policy for abuse. If you believe this was a mistake, please DM the <a href="https://hackclub.slack.com/team/U091HC53CE8" target="_blank" class="underline">Fraud Department</a> on Slack. We do not respond in any other channel, DM or thread.</p>
<p class="text-primary text-left text-lg mb-0"><b>Can I know what caused this?</b> No. We do not disclose the patterns that were detected. Releasing this information would only benefit fraudsters. The fraud team regularly investigates claims of false bans to increase the effectiveness of our detection systems to combat fraud.</p>
</div>
</div>
<% end %>
<div class="flex items-center space-x-2 mt-2">
<p class="italic text-gray-400 m-0">
<%= @flavor_text %>
</p>
</div>
<div id="clock" class="clockicons clock-display"></div>
<% if current_user %>
<h1 class="font-bold mt-1 mb-4 text-5xl text-center">Keep Track of <span class="text-primary">Your</span> Coding Time</h1>
<% else %>
<h1 class="font-bold mt-1 mb-4 text-5xl text-center">Track How Much You <span class="text-primary">Code</span></h1>
<div class="flex flex-col w-full max-w-[50vw] mx-auto mb-22">
<%= link_to hca_auth_path(continue: @continue_param), class: "inline-flex items-center justify-center w-full px-6 py-3 rounded text-white font-bold bg-primary hover:bg-primary/75 transition-colors", data: { turbo: false }, onclick: "let s=this.querySelector('.spinner'),i=this.querySelector('.icon');s.classList.remove('hidden');i.classList.add('hidden');this.style.cssText='pointer-events:none;opacity:0.7'" do %>
<span class="spinner mr-2 hidden"><%= render "shared/spinner", class: "h-6 w-6" %></span>
<img src="/images/icon-rounded.png" class="icon h-6 w-6 mr-2">
<span>Sign in with your Hack Club account</span>
<% end %>
<div class="flex items-center my-4">
<div class="flex-1 border-t border-darkless"></div>
<span class="px-4 text-gray-400 text-sm">or</span>
<div class="flex-1 border-t border-darkless"></div>
</div>
<div class="flex gap-2">
<%= form_tag email_auth_path, class: "relative flex-1", data: { turbo: false } do %>
<div class="relative">
<%= email_field_tag :email, nil, placeholder: "Enter your email to get a sign in link", required: true, class: "w-full px-3 py-3 pr-12 border border-darkless bg-dark placeholder-secondary rounded focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500" %>
<button type="submit" class="absolute right-2 top-1/2 transform -translate-y-1/2 w-8 h-8 p-1 bg-blue-600 hover:bg-blue-700 rounded cursor-pointer border-none flex items-center justify-center transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M13.3 20.275q-.3-.3-.3-.7t.3-.7L16.175 16H7q-.825 0-1.412-.587T5 14V5q0-.425.288-.712T6 4t.713.288T7 5v9h9.175l-2.9-2.9q-.3-.3-.288-.7t.288-.7q.3-.3.7-.312t.7.287L19.3 14.3q.15.15.212.325t.063.375t-.063.375t-.212.325l-4.575 4.575q-.3.3-.712.3t-.713-.3" /></svg>
</button>
</div>
<% end %>
<%= link_to slack_auth_path, class: "flex items-center justify-center px-4 py-3 rounded text-white cursor-pointer bg-dark hover:bg-darkless border border-darkless text-gray-300 transition-colors w-1/4 gap-2" do %>
<span><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-6 h-6"><path fill="currentColor" d="M6 15a2 2 0 0 1-2 2a2 2 0 0 1-2-2a2 2 0 0 1 2-2h2zm1 0a2 2 0 0 1 2-2a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2a2 2 0 0 1-2-2zm2-8a2 2 0 0 1-2-2a2 2 0 0 1 2-2a2 2 0 0 1 2 2v2zm0 1a2 2 0 0 1 2 2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2a2 2 0 0 1 2-2zm8 2a2 2 0 0 1 2-2a2 2 0 0 1 2 2a2 2 0 0 1-2 2h-2zm-1 0a2 2 0 0 1-2 2a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2a2 2 0 0 1 2 2zm-2 8a2 2 0 0 1 2 2a2 2 0 0 1-2 2a2 2 0 0 1-2-2v-2zm0-1a2 2 0 0 1-2-2a2 2 0 0 1 2-2h5a2 2 0 0 1 2 2a2 2 0 0 1-2 2z" /></svg></span>
<span class="hidden xl:inline">Slack Sign In</span>
<% end %>
</div>
</div>
<% if params[:sign_in_email] %>
<div class="text-green-500 mt-4 text-center max-w-[50vw] mx-auto">Check your email for a sign-in link!</div>
<% dev_tool class: "text-center max-w-[50vw] mx-auto mb-4" do %>
Because you're on localhost, <%= link_to "click here to view the email", letter_opener_web_path %>
<% end %>
<% end %>
<div class="w-full flex justify-center overflow-x-none">
<p class="monospace text-center text-primary text-[22px] select-none whitespace-nowrap">==============================================/ h a c k /=============================================</p>
</div>
<div class="mt-8 mb-8">
<h1 class="font-bold mt-1 mb-1 text-4xl">Compatible with your favourite IDEs</h1>
<p class="text-primary monospace text-[20px]">Hackatime works with these code editors and more!</p>
<div id="supported-editors" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4 mt-4">
<% popular_editors = [['VS Code', 'vs-code'], %w[PyCharm pycharm], ['IntelliJ IDEA', 'intellij-idea'], ['Sublime Text', 'sublime-text'], %w[Vim vim], %w[Neovim neovim], ['Android Studio', 'android-studio'], %w[Xcode xcode], %w[Unity unity], %w[Godot godot], %w[Cursor cursor], %w[Zed zed], %w[Terminal terminal], %w[WebStorm webstorm], %w[Eclipse eclipse], %w[Emacs emacs], %w[Jupyter jupyter], %w[OnShape onshape]] %>
<% popular_editors.each do |name, slug| %>
<a href="<%= doc_path("editors/#{slug}") %>" class="bg-darkless rounded-lg p-3 hover:bg-primary/20 transition-all duration-200 text-center block hover:-translate-y-0.5 hover:shadow-lg hover:shadow-primary/20">
<img src="/images/editor-icons/<%= slug %>-128.png" alt="<%= name %>" class="w-12 h-12 mx-auto mb-2">
<div class="text-sm text-white"><%= name %></div>
</a>
<% end %>
</div>
</div>
<div class="w-full flex justify-center overflow-x-none">
<p class="monospace text-center text-primary text-[22px] select-none whitespace-nowrap">-----------------------------------------------------------------------------------------------</p>
</div>
<div class="mt-8 mb-8">
<h1 class="font-bold mt-1 mb-1 text-4xl">Why Hackatime?</h1>
<% if @home_stats&.[](:seconds_tracked) && @home_stats&.[](:users_tracked) %>
<p class="text-primary monospace text-[20px]">
We've tracked over <span class="text-primary"><%= number_with_delimiter(@home_stats[:seconds_tracked] / 3600) %> <%= 'hour'.pluralize(@home_stats[:seconds_tracked] / 3600) %> </span> of coding time across <span class="text-primary"><%= number_with_delimiter(@home_stats[:users_tracked]) %> <%= 'high schooler'.pluralize(@home_stats[:users_tracked]) %> </span> since <span class="text-primary">2025</span>!
</p>
<% end %>
<div class="overflow-x-auto -mx-4 px-4 pb-4 no-scrollbar">
<div class="grid grid-cols-4 gap-4 mt-4 text-center h-30 min-w-[800px]">
<p class="flex flex-col text-3xl justify-center bg-darkless rounded-lg p-3"><span class="text-primary font-bold text-4xl">100%</span><br>free</p>
<p class="flex flex-col text-3xl justify-center bg-darkless rounded-lg p-3">works<br><span class="text-primary font-bold text-4xl">offline</span></p>
<p class="flex flex-col text-3xl justify-center bg-darkless rounded-lg p-3"><span class="text-primary font-bold text-4xl">real time</span><br>stats</p>
<p class="flex flex-col text-3xl justify-center bg-darkless rounded-lg p-3">rise to the<br><span class="text-primary font-bold text-4xl">top #1</span></p>
</div>
</div>
</div>
<div class="w-full flex justify-center overflow-x-none">
<p class="monospace text-center text-primary text-[22px] select-none whitespace-nowrap">--------------------------------| #hackclub | #hackclub | #hackclub |--------------------------------</p>
</div>
<div class="mt-8 mb-8">
<h1 class="font-bold mt-1 mb-1 text-4xl">For your favorite <span class="text-primary">Hack Club</span> events!</h1>
<p class="text-primary monospace text-[20px]">First class support for Hack Club events, and more.</p>
<div class="relative mt-4 mb-4 rounded-lg" style="background: linear-gradient(90deg, #2e1538 0%, #5a2d4a 50%, #a36b80 100%);">
<div class="flex flex-col md:flex-row">
<div class="w-full md:w-1/2 pl-8">
<img src="/images/flagship.png" class="h-auto w-full mx-auto md:mx-0">
</div>
<div class="w-full md:w-1/2 p-8 pl-4 pr-4 grid grid-cols-1 gap-4 ">
<div class="p-8 rounded-lg bg-no-repeat bg-center relative" style="background-image: url('/images/bgBanner.png'); background-size: 100% 100%;">
<h2 class="font-bold text-[22px] text-white drop-shadow-md mb-4 mt-6">Make your first game, get a free ticket to the craziest game jam of 2026!</h2>
<p class="text-white drop-shadow-md text-[18px] mb-4">Meet indie game developers and your favorite YouTubers.</p>
<%= link_to "Start building", "https://flagship.hackclub.com/?utm_source=hackatime", class: "inline-block relative z-10 font-primary font-bold px-6 py-3 rounded-full shadow-lg hover:scale-105 hover:shadow-xl transition-all duration-200", style: "background-color: #f5f0e8; color: #2a2a2a; font-size: 18px; padding-top: 14px;", target: "_blank" %>
</div>
</div>
</div>
</div>
<div class="flex flex-col md:flex-row bg-linear-to-r from-[#EFCCCC] to-[#D35648] mt-4 mb-4 rounded-lg">
<div class="w-full md:w-1/3 -translate-y-5">
<img src="/images/athena.png" class="w-[400px]">
</div>
<div class="w-full md:w-2/3 p-8 pl-4 pr-4">
<img src="/images/athena_award.svg" class="h-24 mb-4">
<p class="text-[18px] m-4">Earn an <b>industry recognized technical certificate</b> for coding 30 hours and building 3 personal projects. Win prizes as you code, and a chance to travel to NYC for 2025's largest high school hackathon for girls.</p>
<%= link_to "Join Athena", "https://athena.hackclub.com/", class: "inline-block bg-white font-primary font-bold text-[#D35648] px-4 py-2 m-4 rounded-[100px] text-[22px] hover:scale-105 transition-transform duration-200", target: "_blank" %>
</div>
</div>
</div>
<% end %>
<% if current_user %>
<% if @show_wakatime_setup_notice %>
<div class="text-left my-8 flex flex-col">
<p class="mb-4 text-xl text-primary">Hello friend! Looks like you are new around here, let's get you set up so you can start tracking your coding time.</p>
<%= link_to "Let's setup Hackatime! Click me :D", my_wakatime_setup_path, class: "inline-block w-auto text-3xl font-bold px-8 py-4 bg-primary text-white rounded shadow-md hover:shadow-lg hover:-translate-y-1 transition-all duration-300 animate-pulse" %>
<div class="flex items-center mt-4 flex-nowrap">
<% if @ssp_users_recent&.any? %>
<div class="flex m-0 ml-0 shrink-0">
<% @ssp_users_recent.each_with_index do |user, index| %>
<div class="relative cursor-pointer transition-transform duration-200 hover:-translate-y-1 hover:z-10 group <%= index > 0 ? '-ml-4' : '' %>">
<div class="absolute -top-9 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-2 py-1 rounded text-xs whitespace-nowrap opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-20">
<%= h(user[:display_name]) %>
<div class="absolute top-full left-1/2 -ml-1 border-l-2 border-r-2 border-t-2 border-transparent border-t-gray-800"></div>
</div>
<img src="<%= user[:avatar_url] %>" alt="<%= h(user[:display_name]) %>" class="w-10 h-10 rounded-full border-2 border-primary object-cover shadow-sm">
</div>
<% end %>
<% if @ssp_users_size && @ssp_users_size > 5 %>
<div class="relative cursor-pointer transition-transform duration-200 hover:-translate-y-1 hover:z-10 group -ml-4" title="See all <%= @ssp_users_size %> users">
<div class="w-10 h-10 rounded-full border-2 border-primary bg-primary text-white font-bold text-sm flex items-center justify-center shadow-sm">+<%= @ssp_users_size - 5 %></div>
<div class="absolute -left-5 top-11 bg-gray-800 rounded-lg shadow-xl p-4 w-80 z-50 max-h-96 overflow-y-auto opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
<h4 class="mt-0 mb-2 text-base text-gray-200 border-b border-gray-600 pb-2">All users who set up Hackatime</h4>
<div class="flex flex-col gap-2">
<% @ssp_users_recent.each do |user| %>
<div class="flex items-center p-1 rounded hover:bg-gray-700 transition-colors duration-200">
<img src="<%= user[:avatar_url] %>" alt="<%= h(user[:display_name]) %>" class="w-8 h-8 rounded-full mr-2 border border-primary">
<span class="font-medium text-sm"><%= h(user[:display_name]) %></span>
</div>
<% end %>
</div>
<div class="absolute -top-2 left-8 w-0 h-0 border-l-2 border-r-2 border-b-2 border-transparent border-b-gray-800"></div>
</div>
</div>
<% end %>
</div>
<% end %>
<% if @ssp_message %>
<p class="m-0 ml-2 italic text-gray-400"><%= @ssp_message %> (this is real data)</p>
<% end %>
</div>
</div>
<% end %>
<% if current_user.github_uid.blank? %>
<div class="bg-dark border border-primary rounded-lg p-4 mb-6">
<div class="flex items-center gap-3">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="text-white shrink-0"><path fill="currentColor" d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2" /></svg>
<div class="flex-1">
<span class="text-white">Link your GitHub account to unlock project linking, show what you're working on, and qualify for leaderboards!</span>
</div>
<%= link_to "Connect GitHub", "/auth/github", class: "bg-primary hover:bg-primary text-white font-medium px-4 py-2 rounded-lg transition-colors duration-200 flex-shrink-0", data: { turbo: false } %>
</div>
</div>
<% end %>
<p class="mt-2">
<% if @show_logged_time_sentence %>
You've logged
<%= short_time_detailed @todays_duration %>
<% if @todays_languages.any? || @todays_editors.any? %>
across
<% if @todays_languages.any? %>
<% if @todays_languages.length >= 4 %>
<%= @todays_languages[0..1].join(", ") %> <span title="<%= @todays_languages[2..].join(", ") %>">(& <%= pluralize(@todays_languages.length - 2, 'other language') %>)</span>
<% else %>
<%= @todays_languages.to_sentence %>
<% end %>
<% end %>
<% if @todays_languages.any? && @todays_editors.any? %>
using
<% end %>
<% if @todays_editors.any? %>
<%= @todays_editors.to_sentence %>
<% end %>
<% end %>
<% else %>
No time logged today... but you can change that!
<% end %>
</p>
<%= turbo_frame_tag "mini_leaderboard", src: mini_leaderboard_static_pages_path, loading: :lazy do %>
<%= render "leaderboards/mini_leaderboard_loading" %>
<% end %>
<%= turbo_frame_tag "filterable_dashboard", src: filterable_dashboard_static_pages_path, loading: :lazy do %>
<%= render "static_pages/filterable_dashboard_loading" %>
<% end %>
<%= turbo_frame_tag "activity_graph", src: activity_graph_static_pages_path, loading: :lazy do %>
<%= render 'static_pages/activity_graph_loading' %>
<% end %>
<% else %>
<% if @leaderboard %>
<h3>Today's Top Hack Clubbers</h3>
<%= render "leaderboards/mini_leaderboard", leaderboard: @leaderboard, current_user: nil %>
<% end %>
<div class="w-full flex justify-center overflow-x-none">
<p class="monospace text-center text-primary text-[22px] select-none whitespace-nowrap">==============================================/ h a c k /=============================================</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 my-8 items-center">
<div>
<h1 class="font-bold mt-1 mb-1 text-5xl">Start hacking with <span class="text-primary">Hackatime</span> now!</h1>
<p class="text-primary monospace text-[20px]">It is super easy to setup, here is a quick guide!</p>
</div>
<div class="w-full relative pb-[56.25%] h-0 overflow-hidden">
<iframe width="1280" height="720" src="https://www.youtube-nocookie.com/embed/FSIxV4u77WQ?rel=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen class="absolute top-0 left-0 w-full h-full rounded-lg"></iframe>
</div>
</div>
<% end %>
</div>