Skip to content

Commit

Permalink
feat(routes/show): add "where to buy" section
Browse files Browse the repository at this point in the history
This patch adds a "where to buy" section to the show page. Similar to
how Rotten Tomatoes has a "where to watch" section on their movie
overview page [[1]], this "where to buy" section gives users one-click
links to shop the looks and products presented in the show.

The "where to buy" section only includes direct links to the specific
collection(s) presented in the show (e.g. for Hermès Spring-Summer 2023,
that link may be [[2]]).

If a direct link to the collection presented in the show does not exist
(e.g. often, Nordstrom and Neiman Marcus and similar retailers will not
maintain a dedicated page per brand collection), we simply show an
`<Empty>` component that has a link to the brand website so users can go
find the products themselves.

Eventually, that behavior will be enhanced once we have the whole:

  Show > Look > Product > Variant > Price (with link to purchase)

...data model hierarchy properly fleshed out in our database. For now,
this works as the next-best option without requiring extensive scraping
to add a show to the database.

[1]: https://www.rottentomatoes.com/m/oppenheimer_2023
[2]: https://www.hermes.com/us/en/category/men/ready-wear/spring-summer-collection

Closes: NC-624
  • Loading branch information
nicholaschiang committed Jul 23, 2023
1 parent 6a0f02b commit a909447
Showing 1 changed file with 60 additions and 1 deletion.
61 changes: 60 additions & 1 deletion app/routes/shows.$showId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ExternalLink } from 'lucide-react'
import { type PropsWithChildren, useMemo } from 'react'

import { Empty } from 'components/empty'
import { buttonVariants } from 'components/ui/button'

import { prisma } from 'db.server'
import { log } from 'log.server'
Expand Down Expand Up @@ -121,7 +122,8 @@ function About({ className }: { className: string }) {
</Empty>
)}
</Section>
<Section header='Collection info'>
<WhereToBuy />
<Section header='Show info'>
<article>{show.description}</article>
</Section>
<Section header={`Critic reviews for ${show.name}`}>
Expand All @@ -144,6 +146,63 @@ function About({ className }: { className: string }) {
)
}

function WhereToBuy() {
const show = useLoaderData<typeof loader>()
const links = show.collections.map((collection) => collection.links).flat()
const brands = show.brands.filter((brand) => brand.url)
return (
<Section header='Where to buy'>
{links.length === 0 && (
<Empty className='mt-2'>
<p>
There are no direct links to this collection on retailer or brand
websites.
</p>
{brands.length > 0 && (
<p>
You can try browsing the{' '}
{brands.map((brand, index) => (
<span>
{index !== 0 && ', '}
<a
target='_blank'
rel='noopener noreferrer'
className='underline inline-flex items-center gap-0.5'
href={brand.url ?? ''}
>
{brand.name}
<ExternalLink className='h-3 w-3' />
</a>
</span>
))}{' '}
website to find these items.
</p>
)}
</Empty>
)}
{links.length > 0 && (
<ul className='mt-2 flex gap-2'>
{links.map((link) => (
<li key={link.id}>
<a
href={link.url}
target='_blank'
rel='noopener noreferrer'
className={cn(buttonVariants({ variant: 'outline' }), 'h-auto')}
>
<img
src={(link.brand ?? link.retailer)?.avatar ?? ''}
alt={(link.brand ?? link.retailer ?? show).name}
/>
</a>
</li>
))}
</ul>
)}
</Section>
)
}

function Looks({ className }: { className: string }) {
const show = useLoaderData<typeof loader>()
return (
Expand Down

0 comments on commit a909447

Please sign in to comment.