show.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5package area
 6
 7import (
 8	"fmt"
 9
10	"git.secluded.site/lune/internal/client"
11	"git.secluded.site/lune/internal/config"
12	"git.secluded.site/lune/internal/deeplink"
13	"git.secluded.site/lune/internal/stats"
14	"git.secluded.site/lune/internal/ui"
15	"github.com/spf13/cobra"
16)
17
18// ShowCmd displays details for a specific area.
19var ShowCmd = &cobra.Command{
20	Use:   "show KEY",
21	Short: "Show area details",
22	Long: `Show detailed information for a configured area.
23
24Displays the area's name, ID, deeplink, goals, and uncompleted task count.`,
25	Args: cobra.ExactArgs(1),
26	RunE: runShow,
27}
28
29func runShow(cmd *cobra.Command, args []string) error {
30	areaKey := args[0]
31
32	cfg, err := config.Load()
33	if err != nil {
34		return err
35	}
36
37	area := cfg.AreaByKey(areaKey)
38	if area == nil {
39		return fmt.Errorf("%w: %s", ErrUnknownArea, areaKey)
40	}
41
42	apiClient, err := client.New()
43	if err != nil {
44		return err
45	}
46
47	counter := stats.NewTaskCounter(apiClient)
48
49	return printAreaDetails(cmd, area, counter)
50}
51
52func printAreaDetails(cmd *cobra.Command, area *config.Area, counter *stats.TaskCounter) error {
53	link, _ := deeplink.Build(deeplink.Area, area.ID)
54
55	fmt.Fprintf(cmd.OutOrStdout(), "%s (%s)\n", ui.H1.Render(area.Name), area.Key)
56	fmt.Fprintf(cmd.OutOrStdout(), "  ID:   %s\n", area.ID)
57	fmt.Fprintf(cmd.OutOrStdout(), "  Link: %s\n", link)
58
59	taskCount, err := counter.UncompletedInArea(cmd.Context(), area.ID)
60	if err != nil {
61		fmt.Fprintf(cmd.OutOrStdout(), "  Tasks: %s\n", ui.Warning.Render("unable to fetch"))
62	} else {
63		fmt.Fprintf(cmd.OutOrStdout(), "  Tasks: %d uncompleted\n", taskCount)
64	}
65
66	if len(area.Goals) == 0 {
67		fmt.Fprintln(cmd.OutOrStdout(), "\n  No goals configured")
68
69		return nil
70	}
71
72	fmt.Fprintln(cmd.OutOrStdout())
73
74	for _, goal := range area.Goals {
75		if err := printGoalSummary(cmd, &goal, counter); err != nil {
76			return err
77		}
78	}
79
80	return nil
81}
82
83func printGoalSummary(cmd *cobra.Command, goal *config.Goal, counter *stats.TaskCounter) error {
84	goalLink, _ := deeplink.Build(deeplink.Goal, goal.ID)
85
86	fmt.Fprintf(cmd.OutOrStdout(), "  %s (%s)\n", ui.H2.Render(goal.Name), goal.Key)
87	fmt.Fprintf(cmd.OutOrStdout(), "    ID:   %s\n", goal.ID)
88	fmt.Fprintf(cmd.OutOrStdout(), "    Link: %s\n", goalLink)
89
90	taskCount, err := counter.UncompletedInGoal(cmd.Context(), goal.ID)
91	if err != nil {
92		fmt.Fprintf(cmd.OutOrStdout(), "    Tasks: %s\n", ui.Warning.Render("unable to fetch"))
93	} else {
94		fmt.Fprintf(cmd.OutOrStdout(), "    Tasks: %d uncompleted\n", taskCount)
95	}
96
97	return nil
98}