package ui import ( "fmt" "mal/web/components/watchlist" ) type AnimeCardProps struct { ID int Title string ImageURL string Href string // Options to customize the card behavior Class string // override default wrapper class ImgClass string // override default image class TitleClass string // override default title class HideTitle bool // if true, do not render the default title block CurrentNode bool // if true, renders a div instead of an anchor tag (useful for graph nodes) Synopsis string // optional synopsis for hover detail PlayHref string // optional play button href (anchored to poster) // Watchlist integration TitleEnglish string TitleJapanese string Airing bool WatchlistStatus string // empty if not in watchlist DisableWatchlist bool // if true, don't render the watchlist button } templ AnimeCard(props AnimeCardProps) {
@animeCardPoster(props) if !props.HideTitle { if props.CurrentNode {
{ props.Title }
} else {
{ props.Title }
} } { children... }
} func cardHref(props AnimeCardProps) string { if props.Href != "" { return props.Href } return fmt.Sprintf("/anime/%d", props.ID) } templ animeCardPoster(props AnimeCardProps) {
if !props.CurrentNode { @animeCardImage(props) } else {
@animeCardImage(props)
}
if props.Synopsis != "" {
{ props.Title }

{ props.Synopsis }

} if props.PlayHref != "" || !props.CurrentNode && !props.DisableWatchlist {
if props.PlayHref != "" { Play } if !props.CurrentNode && !props.DisableWatchlist { @watchlist.CardButton( props.ID, props.Title, props.TitleEnglish, props.TitleJapanese, props.ImageURL, props.Airing, props.WatchlistStatus != "", ) }
}
} templ animeCardImage(props AnimeCardProps) { if props.ImageURL != "" { { } else {
No image
} } func defaultString(val, fallback string) string { if val == "" { return fallback } return val }