diff --git a/components/mostWatchedPerson.templ b/components/mostWatchedPerson.templ
index 2b3f089..4b8e61d 100644
--- a/components/mostWatchedPerson.templ
+++ b/components/mostWatchedPerson.templ
@@ -1,11 +1,15 @@
package components
-import "fmt"
+import (
+ "fmt"
+ "strconv"
+)
type MostWatchedPersonProps struct {
Data []ListItem
Job string
Title string
+ Total int
Year string
Years []string
}
@@ -16,6 +20,9 @@ templ MostWatchedPerson(props MostWatchedPersonProps) {
@Dropdown(DropdownProps{Route: fmt.Sprintf("/stats/most-watched-person/%s", props.Job), Options: props.Years, Value: props.Year})
}
@OrderedList(props.Data, "person")
+
+ { strconv.Itoa( props.Total ) } people total
+
}
}
diff --git a/components/mostWatchedPerson_templ.go b/components/mostWatchedPerson_templ.go
index 27a7305..1812284 100644
--- a/components/mostWatchedPerson_templ.go
+++ b/components/mostWatchedPerson_templ.go
@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
-// templ: version: v0.2.771
+// templ: version: v0.2.778
package components
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@@ -8,12 +8,16 @@ package components
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
-import "fmt"
+import (
+ "fmt"
+ "strconv"
+)
type MostWatchedPersonProps struct {
Data []ListItem
Job string
Title string
+ Total int
Year string
Years []string
}
@@ -21,6 +25,9 @@ type MostWatchedPersonProps struct {
func MostWatchedPerson(props MostWatchedPersonProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
@@ -78,6 +85,23 @@ func MostWatchedPerson(props MostWatchedPersonProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var4 string
+ templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Total))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/mostWatchedPerson.templ`, Line: 24, Col: 32}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" people total
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = Section("", 0).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
@@ -91,6 +115,9 @@ func MostWatchedPerson(props MostWatchedPersonProps) templ.Component {
func MostWatchedGenres(data []ListItem) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
@@ -101,12 +128,12 @@ func MostWatchedGenres(data []ListItem) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var4 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var4 == nil {
- templ_7745c5c3_Var4 = templ.NopComponent
+ templ_7745c5c3_Var5 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var5 == nil {
+ templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
@@ -124,7 +151,7 @@ func MostWatchedGenres(data []ListItem) templ.Component {
}
return templ_7745c5c3_Err
})
- templ_7745c5c3_Err = Section("Most watched genre", 0).Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = Section("Most watched genre", 0).Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/db/queries.sql b/db/queries.sql
index 5d2acb8..fc32fa5 100644
--- a/db/queries.sql
+++ b/db/queries.sql
@@ -260,6 +260,18 @@ ORDER BY
count DESC
LIMIT 10;
+-- name: total-watched-by-job-and-year
+SELECT
+ COUNT(*) AS count
+FROM
+ seen s
+ INNER JOIN movie_person mp ON mp.movie_id = s.movie_id
+WHERE
+ user_id = $1
+ AND mp.job = $2
+ AND ($3 = 'All'
+ OR EXTRACT(YEAR FROM date) = $3::int);
+
-- name: stats-watched-by-year
SELECT
EXTRACT(YEAR FROM date) AS label,
diff --git a/handlers/stats.go b/handlers/stats.go
index 727f23e..fb2c05d 100644
--- a/handlers/stats.go
+++ b/handlers/stats.go
@@ -37,9 +37,11 @@ func HandleGetStats(c *fiber.Ctx) error {
var movies []components.ListItem
var shortestAndLongest types.Movies
var wilhelms []int
+ var totals []components.ListItem
userId := c.Locals("UserId").(string)
now := time.Now()
+ year := now.Format("2006")
currentYear := now.Format("2006-01-02 15:04:05")
err := db.Dot.Select(db.Client, &movies, "stats-most-watched-movies", userId)
@@ -56,6 +58,12 @@ func HandleGetStats(c *fiber.Ctx) error {
return err
}
+ err = db.Dot.Select(db.Client, &totals, "total-watched-by-job-and-year", userId, "cast", year)
+
+ if err != nil {
+ return err
+ }
+
err = db.Dot.Get(db.Client, &stats, "stats-data", userId)
if err != nil {
@@ -128,7 +136,11 @@ func HandleGetStats(c *fiber.Ctx) error {
}
}
- year := now.Format("2006")
+ totalCast := 0
+
+ if len(totals) > 0 {
+ totalCast = totals[0].Count
+ }
return utils.TemplRender(c, views.Stats(
views.StatsProps{
@@ -141,6 +153,7 @@ func HandleGetStats(c *fiber.Ctx) error {
Ratings: ratings,
SeenThisYear: seenThisYearByMonth,
Stats: stats,
+ TotalCast: totalCast,
WatchedByYear: watchedByYear,
Year: year,
YearRatings: yearRatings,
@@ -152,6 +165,7 @@ func HandleGetStats(c *fiber.Ctx) error {
func HandleGetMostWatchedByJob(c *fiber.Ctx) error {
var persons []components.ListItem
+ var totals []components.ListItem
job := c.Params("job")
year := c.Query("year", "All")
@@ -165,14 +179,27 @@ func HandleGetMostWatchedByJob(c *fiber.Ctx) error {
return err
}
- return utils.TemplRender(c, components.MostWatchedPerson(components.MostWatchedPersonProps{
- Data: persons,
- Job: job,
- Title: cases.Title(language.English).String(job),
- Year: year,
- Years: years,
- },
- ))
+ err = db.Dot.Select(db.Client, &totals, "total-watched-by-job-and-year", userId, job, year)
+
+ if err != nil {
+ return err
+ }
+
+ totalJob := 0
+
+ if len(totals) > 0 {
+ totalJob = totals[0].Count
+ }
+
+ return utils.TemplRender(c, components.MostWatchedPerson(
+ components.MostWatchedPersonProps{
+ Data: persons,
+ Job: job,
+ Title: cases.Title(language.English).String(job),
+ Total: totalJob,
+ Year: year,
+ Years: years,
+ }))
}
func getGraphWithQuery(query string, userId string) ([]types.Bar, error) {
diff --git a/public/styles.323df8.css b/public/styles.5709e2.css
similarity index 99%
rename from public/styles.323df8.css
rename to public/styles.5709e2.css
index 52b5ff4..fa50df8 100644
--- a/public/styles.323df8.css
+++ b/public/styles.5709e2.css
@@ -913,6 +913,10 @@ video {
text-align: center;
}
+.text-right {
+ text-align: right;
+}
+
.text-base {
font-size: 1rem;
line-height: 1.5rem;
diff --git a/public/styles.css b/public/styles.css
index 7d30656..7e995d8 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -923,6 +923,10 @@ video {
text-align: center;
}
+.text-right {
+ text-align: right;
+}
+
.text-base {
font-size: 1rem;
line-height: 1.5rem;
diff --git a/views/stats.templ b/views/stats.templ
index ff3ae56..fe71560 100644
--- a/views/stats.templ
+++ b/views/stats.templ
@@ -27,6 +27,7 @@ type StatsProps struct {
SeenThisYear []types.Bar
ShortestAndLongestMovie types.Movies
Stats types.Stats
+ TotalCast int
WatchedByYear []types.Bar
WilhelmScreams int
Year string
@@ -174,6 +175,7 @@ templ Stats(props StatsProps) {
Job: "cast",
Title: "Cast",
Data: props.MostWatchedCast,
+ Total: props.TotalCast,
Year: "All",
Years: append([]string{"All"}, props.Years...),
})
diff --git a/views/stats_templ.go b/views/stats_templ.go
index 845aa9a..9a08586 100644
--- a/views/stats_templ.go
+++ b/views/stats_templ.go
@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
-// templ: version: v0.2.771
+// templ: version: v0.2.778
package views
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@@ -19,6 +19,9 @@ import (
func statsSection(job string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
@@ -66,6 +69,7 @@ type StatsProps struct {
SeenThisYear []types.Bar
ShortestAndLongestMovie types.Movies
Stats types.Stats
+ TotalCast int
WatchedByYear []types.Bar
WilhelmScreams int
Year string
@@ -76,6 +80,9 @@ type StatsProps struct {
func Stats(props StatsProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
@@ -172,7 +179,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Stats.UniqueMovies))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 55, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 56, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@@ -206,7 +213,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Stats.SeenWithRewatches))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 61, Col: 53}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 62, Col: 53}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -240,7 +247,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.FormattedTotalRuntime)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 67, Col: 37}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 68, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
@@ -275,7 +282,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.WilhelmScreams))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 74, Col: 45}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 75, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -323,7 +330,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(props.Stats.TopImdbTitle)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 84, Col: 35}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 85, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@@ -336,7 +343,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatFloat(props.Stats.TopImdbRating, 'f', 1, 64))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 87, Col: 70}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 88, Col: 70}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
@@ -386,7 +393,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(props.BestOfTheYear.Title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 95, Col: 37}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 96, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
@@ -410,7 +417,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatInt(props.BestOfTheYear.Rating.Int64, 10))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 99, Col: 69}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 100, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
@@ -462,7 +469,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(props.ShortestAndLongestMovie[0].Title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 109, Col: 50}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 110, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
@@ -481,7 +488,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(utils.FormatRuntime(props.ShortestAndLongestMovie[0].Runtime))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 112, Col: 74}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 113, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
@@ -530,7 +537,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(props.ShortestAndLongestMovie[1].Title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 119, Col: 50}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 120, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
@@ -549,7 +556,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var31 string
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(utils.FormatRuntime(props.ShortestAndLongestMovie[1].Runtime))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 122, Col: 74}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 123, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil {
@@ -660,7 +667,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var36 string
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(year.Label)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 155, Col: 22}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 156, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
if templ_7745c5c3_Err != nil {
@@ -700,7 +707,7 @@ func Stats(props StatsProps) templ.Component {
var templ_7745c5c3_Var39 string
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(year.Value))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 162, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/stats.templ`, Line: 163, Col: 36}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
if templ_7745c5c3_Err != nil {
@@ -751,6 +758,7 @@ func Stats(props StatsProps) templ.Component {
Job: "cast",
Title: "Cast",
Data: props.MostWatchedCast,
+ Total: props.TotalCast,
Year: "All",
Years: append([]string{"All"}, props.Years...),
}).Render(ctx, templ_7745c5c3_Buffer)