Skip to content

Commit

Permalink
feat(movie): add reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
believer committed Oct 1, 2024
1 parent a835adf commit 3f8a140
Show file tree
Hide file tree
Showing 8 changed files with 463 additions and 309 deletions.
11 changes: 11 additions & 0 deletions components/review.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package components

import "believer/movies/types"

templ Review(props types.Review) {
if props.Content != "" {
@Section("Review", 0) {
{ props.Content }
}
}
}
67 changes: 67 additions & 0 deletions components/review_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions db/db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,16 @@ func InitializeConnection() error {
return err
}

movieQueries, err := dotsql.LoadFromFile("./db/movieQueries.sql")

if err != nil {
return err
}

dot := dotsql.Merge(
generalQueries,
genreQueries,
movieQueries,
seriesQueries,
statsQueries,
watchlistQueries,
Expand Down
12 changes: 12 additions & 0 deletions db/movieQueries.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- name: review-by-movie-id
SELECT
id,
content,
private
FROM
review
WHERE
movie_id = $1
AND user_id = $2
AND private IS FALSE;

16 changes: 15 additions & 1 deletion handlers/movies.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

func HandleGetMovieByID(c *fiber.Ctx) error {
var movie types.Movie
var review types.Review

backParam := c.QueryBool("back", false)

Expand All @@ -44,7 +45,20 @@ func HandleGetMovieByID(c *fiber.Ctx) error {
}
}

return utils.TemplRender(c, views.Movie(movie, backParam))
err = db.Dot.Get(db.Client, &review, "review-by-movie-id", id, userId)

if err != nil {
if err != sql.ErrNoRows {
return err
}
}

return utils.TemplRender(c, views.Movie(
views.MovieProps{
Movie: movie,
Review: review,
Back: backParam,
}))
}

type CastDB struct {
Expand Down
7 changes: 7 additions & 0 deletions types/review.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package types

type Review struct {
ID int `db:"id"`
Content string `db:"content"`
Private bool `db:"private"`
}
53 changes: 30 additions & 23 deletions views/movie.templ
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,62 @@ import (
// TODO: View transition of elements doesn't work because we can't have a
// parameterized "style" attribute in the template. At least yet...
// https://github.com/a-h/templ/issues/88
templ Movie(movie types.Movie, back bool) {
@Layout(LayoutProps{Title: movie.Title, Description: movie.Overview}) {
<div class="mx-auto flex max-w-xl flex-col gap-8 px-5 py-8">
@components.H1(movie.Title, back)
if movie.Overview != "" {
<p class="text-neutral-500 dark:text-neutral-400">{ movie.Overview }</p>

type MovieProps struct {
Back bool
Movie types.Movie
Review types.Review
}

templ Movie(props MovieProps) {
@Layout(LayoutProps{Title: props.Movie.Title, Description: props.Movie.Overview}) {
@StandardBody(props.Movie.Title) {
if props.Movie.Overview != "" {
<p class="text-neutral-500 dark:text-neutral-400">{ props.Movie.Overview }</p>
}
@components.Review(props.Review)
@components.Section("Metadata", 0) {
@components.DescriptionList() {
if movie.Tagline != "" {
if props.Movie.Tagline != "" {
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Tagline"}) {
{ movie.Tagline }
{ props.Movie.Tagline }
}
}
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Release date"}) {
@components.SimpleLink(components.SimpleLinkProps{Href: movie.LinkToYear()}) {
{ movie.ISOReleaseDate() }
@components.SimpleLink(components.SimpleLinkProps{Href: props.Movie.LinkToYear()}) {
{ props.Movie.ISOReleaseDate() }
}
}
if movie.Runtime != 0 {
if props.Movie.Runtime != 0 {
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Runtime"}) {
{ movie.RuntimeFormatted() }
{ props.Movie.RuntimeFormatted() }
}
}
if movie.Series.Valid && movie.NumberInSeries.Valid {
if props.Movie.Series.Valid && props.Movie.NumberInSeries.Valid {
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Series"}) {
@components.SimpleLink(components.SimpleLinkProps{Href: movie.LinkToSeries()}) {
{ movie.Series.String } #{ strconv.FormatInt( movie.NumberInSeries.Int64, 10 ) }
@components.SimpleLink(components.SimpleLinkProps{Href: props.Movie.LinkToSeries()}) {
{ props.Movie.Series.String } #{ strconv.FormatInt( props.Movie.NumberInSeries.Int64, 10 ) }
}
}
}
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "IMDb"}) {
<a
href={ templ.URL(fmt.Sprintf("https://www.imdb.com/title/%s", movie.ImdbId)) }
href={ templ.URL(fmt.Sprintf("https://www.imdb.com/title/%s", props.Movie.ImdbId)) }
class="inline-flex items-center gap-1 focus:outline-none focus-visible:rounded-sm focus-visible:outline-dashed focus-visible:outline-offset-2 focus-visible:outline-neutral-400 dark:focus-visible:outline-neutral-600"
target="_blank"
rel="noopener noreferrer"
>
<span
class="border-b border-dashed border-neutral-500 dark:border-neutral-400"
>
{ movie.ImdbId }
{ props.Movie.ImdbId }
</span>
@components.IconExternalLink()
</a>
}
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Genres", IsTabular: false}) {
<div class="flex flex-wrap gap-2">
for _, genre := range movie.Genres {
for _, genre := range props.Movie.Genres {
<a
class="inline-flex items-center gap-1 focus:outline-none focus-visible:rounded-sm focus-visible:outline-dashed focus-visible:outline-offset-2 focus-visible:outline-neutral-400 dark:focus-visible:outline-neutral-600 border-b border-dashed border-neutral-500 dark:border-neutral-400"
href={ templ.URL(genre.LinkTo()) }
Expand All @@ -68,21 +75,21 @@ templ Movie(movie types.Movie, back bool) {
}
</div>
}
if movie.Rating.Valid {
if props.Movie.Rating.Valid {
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Rating", IsTabular: false}) {
{ strconv.FormatInt(movie.Rating.Int64, 10) }
{ strconv.FormatInt(props.Movie.Rating.Int64, 10) }
}
}
@components.DescriptionListItem(components.DescriptionListItemProps{Detail: "Watched", IsTabular: false}) {
<span hx-get={ fmt.Sprintf("/movie/%d/seen?imdbId=%s", movie.ID, movie.ImdbId) } hx-trigger="load"></span>
<span hx-get={ fmt.Sprintf("/movie/%d/seen?imdbId=%s", props.Movie.ID, props.Movie.ImdbId) } hx-trigger="load"></span>
}
}
}
<div
hx-get={ fmt.Sprintf("/movie/%d/cast", movie.ID) }
hx-get={ fmt.Sprintf("/movie/%d/cast", props.Movie.ID) }
hx-trigger="load"
hx-swap="outerHTML"
></div>
</div>
}
}
}
Loading

0 comments on commit 3f8a140

Please sign in to comment.