Files
ghglance/internal/card/card.go
T
tiennm99 01c812158f feat(card): add records card with six lifetime personal-bests
New records.svg surfaces extremes the existing aggregate cards don't:
peak day (count + date), peak month, first contribution, lifetime
active days, account age in fractional years, and distinct languages
used. All values derive from data already fetched — no new GraphQL
queries. Three new octicon paths (calendar, history, globe) added to
icons.go; existing icons reused where they fit.
2026-05-09 09:47:38 +07:00

60 lines
1.6 KiB
Go

// Package card renders Profile data into SVG cards on disk.
package card
import (
"fmt"
"os"
"path/filepath"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
)
// Card renders one SVG for a Profile under the given theme.
type Card interface {
// Filename is the on-disk basename (e.g. "profile-details.svg").
Filename() string
// SVG returns the rendered SVG bytes.
SVG(p *github.Profile, t theme.Theme) ([]byte, error)
}
// allCards is the ordered list rendered by RenderAll. Filenames are plain
// kebab-case — README authors embed them by name, not by lexicographic order.
var allCards = []Card{
profileCard{},
reposPerLanguageCard{},
mostCommitLanguageCard{},
statsCard{},
productiveCard{},
productiveWeekdayCard{},
contributionsCard{},
contributionsHeatmapCard{},
topStarredReposCard{},
streakCard{},
mostCommitLanguageAllTimeCard{},
productiveAllTimeCard{},
productiveWeekdayAllTimeCard{},
contributionsAllTimeCard{},
contributionsByYearCard{},
recordsCard{},
}
// RenderAll writes every card into outDir/<themeID>/.
func RenderAll(p *github.Profile, t theme.Theme, outDir string) error {
dir := filepath.Join(outDir, t.ID)
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir %s: %w", dir, err)
}
for _, c := range allCards {
data, err := c.SVG(p, t)
if err != nil {
return fmt.Errorf("render %s: %w", c.Filename(), err)
}
path := filepath.Join(dir, c.Filename())
if err := os.WriteFile(path, data, 0o644); err != nil {
return fmt.Errorf("write %s: %w", path, err)
}
}
return nil
}