mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 16:38:23 +00:00
* fix: use owner/repo format for project badges Updates badge URLs to use GitHub-style owner/repo format (e.g., "hackclub/hackatime") instead of project names. This ensures compatibility with external badge services that expect repository paths. Changes: - Add Repository#full_path method to get owner/repo format - Update settings controller to pass both display names and repo paths - Update Badges component to display project names but use repo paths in URLs * fix: improve user lookup in API v1 stats endpoint Use the robust lookup_user method for username parameter in the /api/v1/stats endpoint to ensure consistent user lookup across all API endpoints. This properly handles Slack UIDs (HCA IDs), numeric user IDs, and usernames in the correct priority order. * fix: reduce clutter on new user homepage Simplify the new user experience by: - Removing redundant "Hello friend" text from setup notice (header already provides context) - Hiding GitHub link banner when setup notice is shown to focus user on primary action This reduces visual clutter and helps new users focus on completing setup first. * fix: enable full app layout for new OAuth application page Remove layout=false directive that was preventing the app header and navigation from appearing on the new OAuth application creation page. * fix: add antigravity editor to docs Add documentation for Antigravity, a VSCode fork from Google with built-in AI features. Includes setup instructions for tracking time with Hackatime using the WakaTime extension. * fix: improve stat card subtitle positioning Remove absolute positioning from subtitle text to allow it to flow naturally after the main value. This prevents the subtitle from being pushed to the bottom when other cards have longer content. * fix: align settings action buttons to card end on larger screens Remove width constraint from footer to allow action buttons to align to the right edge of the full card width instead of being constrained to a narrower container. * fix: improve heartbeat importer visibility on light themes Update import provider cards and radio buttons to have better contrast on light themes: - Use bg-surface-100 instead of bg-darker for better card visibility - Increase radio button border thickness and use darker border color - Add hover and focus states for better interactivity * Split up settings controller + perf + goal display * Make stat card subtitles larger * Fix AG + VS Code * Remove Shiba refs * Bundle update
176 lines
5.1 KiB
Svelte
176 lines
5.1 KiB
Svelte
<script lang="ts">
|
|
import { Deferred, router } from "@inertiajs/svelte";
|
|
import type { ActivityGraphData } from "../../types/index";
|
|
import BanNotice from "./signedIn/BanNotice.svelte";
|
|
import GitHubLinkBanner from "./signedIn/GitHubLinkBanner.svelte";
|
|
import SetupNotice from "./signedIn/SetupNotice.svelte";
|
|
import TodaySentence from "./signedIn/TodaySentence.svelte";
|
|
import TodaySentenceSkeleton from "./signedIn/TodaySentenceSkeleton.svelte";
|
|
import Dashboard from "./signedIn/Dashboard.svelte";
|
|
import DashboardSkeleton from "./signedIn/DashboardSkeleton.svelte";
|
|
import ActivityGraph from "./signedIn/ActivityGraph.svelte";
|
|
import ActivityGraphSkeleton from "./signedIn/ActivityGraphSkeleton.svelte";
|
|
|
|
type SocialProofUser = { display_name: string; avatar_url: string };
|
|
|
|
type FilterableDashboardData = {
|
|
total_time: number;
|
|
total_heartbeats: number;
|
|
top_project: string | null;
|
|
top_language: string | null;
|
|
top_editor: string | null;
|
|
top_operating_system: string | null;
|
|
project_durations: Record<string, number>;
|
|
language_stats: Record<string, number>;
|
|
editor_stats: Record<string, number>;
|
|
operating_system_stats: Record<string, number>;
|
|
category_stats: Record<string, number>;
|
|
weekly_project_stats: Record<string, Record<string, number>>;
|
|
project: string[];
|
|
language: string[];
|
|
editor: string[];
|
|
operating_system: string[];
|
|
category: string[];
|
|
selected_interval: string;
|
|
selected_from: string;
|
|
selected_to: string;
|
|
selected_project: string[];
|
|
selected_language: string[];
|
|
selected_editor: string[];
|
|
selected_operating_system: string[];
|
|
selected_category: string[];
|
|
};
|
|
|
|
type TodayStats = {
|
|
show_logged_time_sentence: boolean;
|
|
todays_duration_display: string;
|
|
todays_languages: string[];
|
|
todays_editors: string[];
|
|
};
|
|
|
|
type ProgrammingGoalProgress = {
|
|
id: string;
|
|
period: "day" | "week" | "month";
|
|
target_seconds: number;
|
|
tracked_seconds: number;
|
|
completion_percent: number;
|
|
complete: boolean;
|
|
languages: string[];
|
|
projects: string[];
|
|
period_end: string;
|
|
};
|
|
|
|
let {
|
|
flavor_text,
|
|
trust_level_red,
|
|
show_wakatime_setup_notice,
|
|
ssp_message,
|
|
ssp_users_recent,
|
|
ssp_users_size,
|
|
github_uid_blank,
|
|
github_auth_path,
|
|
wakatime_setup_path,
|
|
dashboard_stats,
|
|
}: {
|
|
flavor_text: string;
|
|
trust_level_red: boolean;
|
|
show_wakatime_setup_notice: boolean;
|
|
ssp_message?: string | null;
|
|
ssp_users_recent: SocialProofUser[];
|
|
ssp_users_size: number;
|
|
github_uid_blank: boolean;
|
|
github_auth_path: string;
|
|
wakatime_setup_path: string;
|
|
dashboard_stats?: {
|
|
filterable_dashboard_data: FilterableDashboardData;
|
|
activity_graph: ActivityGraphData;
|
|
today_stats: TodayStats;
|
|
programming_goals_progress: ProgrammingGoalProgress[];
|
|
};
|
|
} = $props();
|
|
|
|
function refreshDashboardData(search: string) {
|
|
router.visit(`${window.location.pathname}${search}`, {
|
|
only: ["dashboard_stats"],
|
|
preserveState: true,
|
|
preserveScroll: true,
|
|
replace: true,
|
|
async: true,
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<div>
|
|
<!-- Header Section -->
|
|
<div class="mb-8">
|
|
<div class="flex items-center space-x-2">
|
|
<p class="italic text-muted m-0">
|
|
{@html flavor_text}
|
|
</p>
|
|
</div>
|
|
|
|
<h1 class="font-bold mt-2 mb-4 text-3xl md:text-4xl">
|
|
Keep Track of <span class="text-primary">Your</span> Coding Time
|
|
</h1>
|
|
</div>
|
|
|
|
{#if trust_level_red}
|
|
<BanNotice />
|
|
{/if}
|
|
|
|
{#if show_wakatime_setup_notice}
|
|
<SetupNotice
|
|
{wakatime_setup_path}
|
|
{ssp_message}
|
|
{ssp_users_recent}
|
|
{ssp_users_size}
|
|
/>
|
|
{:else if github_uid_blank}
|
|
<GitHubLinkBanner {github_auth_path} />
|
|
{/if}
|
|
|
|
<Deferred data="dashboard_stats">
|
|
{#snippet fallback()}
|
|
<div class="flex flex-col gap-8">
|
|
<div>
|
|
<TodaySentenceSkeleton />
|
|
</div>
|
|
<DashboardSkeleton />
|
|
<ActivityGraphSkeleton />
|
|
</div>
|
|
{/snippet}
|
|
|
|
{#snippet children({ reloading })}
|
|
<div class="flex flex-col gap-8" class:opacity-60={reloading}>
|
|
<!-- Today Stats -->
|
|
<div>
|
|
{#if dashboard_stats?.today_stats}
|
|
<TodaySentence
|
|
show_logged_time_sentence={dashboard_stats.today_stats
|
|
.show_logged_time_sentence}
|
|
todays_duration_display={dashboard_stats.today_stats
|
|
.todays_duration_display}
|
|
todays_languages={dashboard_stats.today_stats.todays_languages}
|
|
todays_editors={dashboard_stats.today_stats.todays_editors}
|
|
/>
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Main Dashboard -->
|
|
{#if dashboard_stats?.filterable_dashboard_data}
|
|
<Dashboard
|
|
data={dashboard_stats.filterable_dashboard_data}
|
|
programmingGoalsProgress={dashboard_stats.programming_goals_progress ||
|
|
[]}
|
|
onFiltersChange={refreshDashboardData}
|
|
/>
|
|
{/if}
|
|
|
|
<!-- Activity Graph -->
|
|
{#if dashboard_stats?.activity_graph}
|
|
<ActivityGraph data={dashboard_stats.activity_graph} />
|
|
{/if}
|
|
</div>
|
|
{/snippet}
|
|
</Deferred>
|
|
</div>
|