From 792eafecbc106251cbb012b371bd5a6638b6f6bd Mon Sep 17 00:00:00 2001 From: Iqro-dev Date: Fri, 9 Aug 2024 16:29:46 +0200 Subject: [PATCH 1/3] feat(items-list): add new card view --- app/components/items/cards/item-card.tsx | 41 +- .../items/list/items-list.skeleton.tsx | 17 +- .../items/list/items-list.stories.tsx | 2 +- app/components/items/list/items-list.tsx | 40 +- app/components/items/misc/item-artists.tsx | 6 +- .../components/common/selects/select-view.tsx | 13 +- app/profile/enums/view.ts | 1 + app/profile/sections/items-section.tsx | 8 +- tests/snapshots/item-artists.spec.tsx.snap | 122 +- tests/snapshots/item-card.spec.tsx.snap | 176 ++- .../item-header-section.spec.tsx.snap | 144 +- tests/snapshots/item-top-card.spec.tsx.snap | 180 ++- .../items-list-element.spec.tsx.snap | 288 ++-- tests/snapshots/items-list.spec.tsx.snap | 588 ++++++++ tests/snapshots/items-section.spec.tsx.snap | 1254 ++++++++++++++--- 15 files changed, 2284 insertions(+), 596 deletions(-) diff --git a/app/components/items/cards/item-card.tsx b/app/components/items/cards/item-card.tsx index 259f2081..4fb6f5e5 100644 --- a/app/components/items/cards/item-card.tsx +++ b/app/components/items/cards/item-card.tsx @@ -1,10 +1,11 @@ 'use client' -import { ItemImage, ItemName, ItemArtists } from '../misc' +import { ItemArtists, ItemImage, ItemName } from '../misc' -import { Card } from '@app/components/ui/card' -import { SpotifyLink } from '@app/components/common' import type { AlbumEntity, ArtistEntity, TrackEntity } from '@app/api/types' +import { SpotifyLink } from '@app/components/common' +import { Card } from '@app/components/ui/card' +import { cn } from '@app/utils/cn' interface ItemCardAlbum extends Pick { @@ -46,27 +47,35 @@ function ItemCard({ -
+
-
- {albumType ? ( -
- {new Date(releaseDate).getFullYear()} •  - {albumType} -
- ) : album ? ( - - ) : ( -
- )} + {(album ?? albumType) ? ( +
+ {albumType && ( +
+ {new Date(releaseDate).getFullYear()} •  + {albumType} +
+ )} + + {album && ( +
+ +
+ )} + {(album ?? artists) && } +
+ ) : ( -
+ )}
) diff --git a/app/components/items/list/items-list.skeleton.tsx b/app/components/items/list/items-list.skeleton.tsx index c7d504b4..c108bee4 100644 --- a/app/components/items/list/items-list.skeleton.tsx +++ b/app/components/items/list/items-list.skeleton.tsx @@ -25,7 +25,7 @@ function ItemsListSkeleton({ }: ItemsListSkeleton.Props) { return (
- {view === View.CARD && ( + {view === View.TOP && ( <>
@@ -87,6 +87,21 @@ function ItemsListSkeleton({ ))}
)} + + {view === View.CARD && ( +
+ {Array.from({ length: 10 }) + .fill(0) + .map((_, index) => ( + + ))} +
+ )}
) } diff --git a/app/components/items/list/items-list.stories.tsx b/app/components/items/list/items-list.stories.tsx index 37a6970e..db7a9d01 100644 --- a/app/components/items/list/items-list.stories.tsx +++ b/app/components/items/list/items-list.stories.tsx @@ -141,7 +141,7 @@ export const Skeleton: ItemsListStory = { } export const SkeletonWithTop: ItemsListStory = { - render: () => , + render: () => , } export const SkeletonWithArtists: ItemsListStory = { diff --git a/app/components/items/list/items-list.tsx b/app/components/items/list/items-list.tsx index 72d64dc0..3785ce95 100644 --- a/app/components/items/list/items-list.tsx +++ b/app/components/items/list/items-list.tsx @@ -2,7 +2,7 @@ import type { HtmlHTMLAttributes } from 'react' -import { ItemTopCard } from '../cards' +import { ItemCard, ItemTopCard } from '../cards' import { formatItems } from '../helpers' import type { ItemPosition } from '../misc' @@ -32,6 +32,7 @@ namespace ItemsList { | TrackEntity[] | RigtchStatsResponse isTop?: boolean + isCard?: boolean positionSize?: ItemPosition.Props['size'] positionClassName?: string lastItemSeparator?: boolean @@ -44,6 +45,7 @@ namespace ItemsList { function ItemsList({ items, isTop, + isCard, positionSize, className, positionClassName, @@ -90,22 +92,32 @@ function ItemsList({ )} -
+
{sortedItems.slice(isTop ? 3 : 0).map((item, index, items) => (
- {/* @ts-expect-error: conditional types are already handled */} - + {isCard ? ( + + ) : ( + /* @ts-expect-error: conditional types are already handled */ + + )} - {items.length === index + 1 ? ( + {isCard ? null : items.length === index + 1 ? ( lastItemSeparator ? ( ) : null diff --git a/app/components/items/misc/item-artists.tsx b/app/components/items/misc/item-artists.tsx index 1a2e5934..863a80ab 100644 --- a/app/components/items/misc/item-artists.tsx +++ b/app/components/items/misc/item-artists.tsx @@ -1,8 +1,8 @@ 'use client' +import type { ArtistEntity } from '@app/api/types' import { LinkButton } from '@app/components/common/buttons' import { cn } from '@app/utils/cn' -import type { ArtistEntity } from '@app/api/types' namespace ItemArtists { export type Props = Readonly< @@ -14,7 +14,7 @@ namespace ItemArtists { function ItemArtists({ artists, className }: ItemArtists.Props) { return ( - <> + {artists.map(({ name, id }, index) => ( , } ))} - + ) } diff --git a/app/profile/components/common/selects/select-view.tsx b/app/profile/components/common/selects/select-view.tsx index a202eb23..0256d00d 100644 --- a/app/profile/components/common/selects/select-view.tsx +++ b/app/profile/components/common/selects/select-view.tsx @@ -1,7 +1,7 @@ 'use client' import { usePathname, useRouter, useSearchParams } from 'next/navigation' -import { LuLayers, LuList } from 'react-icons/lu' +import { LuLayers, LuList, LuStar } from 'react-icons/lu' import type { ProfileSelectProps } from './props' @@ -19,15 +19,20 @@ import { formatSearchParams } from '@app/utils/formatters' export function SelectView({ initialValue }: ProfileSelectProps) { const viewOptions = [ { - icon: , - value: View.CARD, - label: 'Card', + icon: , + value: View.TOP, + label: 'Top', }, { icon: , value: View.LIST, label: 'List', }, + { + icon: , + value: View.CARD, + label: 'Card', + }, ] const pathname = usePathname() diff --git a/app/profile/enums/view.ts b/app/profile/enums/view.ts index 26b6e304..dc2245ca 100644 --- a/app/profile/enums/view.ts +++ b/app/profile/enums/view.ts @@ -1,4 +1,5 @@ export enum View { LIST = 'list', + TOP = 'TOP', CARD = 'card', } diff --git a/app/profile/sections/items-section.tsx b/app/profile/sections/items-section.tsx index a55d2ba4..df44ef41 100644 --- a/app/profile/sections/items-section.tsx +++ b/app/profile/sections/items-section.tsx @@ -1,6 +1,5 @@ import { NoDataAlert } from '../components/common' -import { DefaultSection } from '@app/sections' import type { AlbumEntity, ArtistEntity, @@ -9,6 +8,7 @@ import type { } from '@app/api/types' import { ItemsList } from '@app/components/items/list' import { View } from '@app/profile/enums' +import { DefaultSection } from '@app/sections' namespace ItemsSection { export type Props = Readonly< @@ -31,7 +31,11 @@ function ItemsSection({ return ( {items.length > 0 && ( - + )} {items.length === 0 && } diff --git a/tests/snapshots/item-artists.spec.tsx.snap b/tests/snapshots/item-artists.spec.tsx.snap index 77accd4d..de2bd607 100644 --- a/tests/snapshots/item-artists.spec.tsx.snap +++ b/tests/snapshots/item-artists.spec.tsx.snap @@ -5,6 +5,24 @@ exports[`ItemArtists > should match snapshot with artist entity 1`] = ` "asFragment": [Function], "baseElement":
+ + + + Darkthrone + + + +
+ , + "container": - , - "container": , "debug": [Function], @@ -84,6 +92,57 @@ exports[`ItemArtists > should match snapshot with multiple artist entities 1`] = "asFragment": [Function], "baseElement":
+ + + + Darkthrone + + + , + + + + + Darkthrone + + + , + + + + + Darkthrone + + + , + + + + + Darkthrone + + + +
+ , + "container": - , - "container":
- - - Darkthrone - - - , - - - - - Darkthrone - - - , - - - - - Darkthrone - - - , - - - - - Darkthrone -
, "debug": [Function], diff --git a/tests/snapshots/item-card.spec.tsx.snap b/tests/snapshots/item-card.spec.tsx.snap index 79f26afa..e58bf87f 100644 --- a/tests/snapshots/item-card.spec.tsx.snap +++ b/tests/snapshots/item-card.spec.tsx.snap @@ -20,7 +20,9 @@ exports[`ItemCard > should match snapshot as album 1`] = ` style="color: transparent; min-height: 200px; max-height: 200px; min-width: 200px; max-width: 200px; object-fit: cover;" width="200" /> -
+
should match snapshot as album 1`] = ` Album 1

+<<<<<<< HEAD
@@ -95,6 +98,8 @@ exports[`ItemCard > should match snapshot as album 1`] = ` class="flex flex-row justify-between" >
+======= +>>>>>>> 809dab4 (feat(items-list): add new card view)
+ , + "container": , "debug": [Function], "findAllByAltText": [Function], @@ -197,7 +258,9 @@ exports[`ItemCard > should match snapshot as artist 1`] = ` style="color: transparent; min-height: 200px; max-height: 200px; min-width: 200px; max-width: 200px; object-fit: cover;" width="200" /> -
+
should match snapshot as artist 1`] = ` Darkthrone

+<<<<<<< HEAD
@@ -272,6 +336,8 @@ exports[`ItemCard > should match snapshot as artist 1`] = ` class="flex flex-row justify-between" >
+======= +>>>>>>> 809dab4 (feat(items-list): add new card view)
+ , + "container": , "debug": [Function], "findAllByAltText": [Function], @@ -374,7 +496,9 @@ exports[`ItemCard > should match snapshot as track 1`] = ` style="color: transparent; min-height: 200px; max-height: 200px; min-width: 200px; max-width: 200px; object-fit: cover;" width="200" /> -
+
should match snapshot as track 1`] = `
@@ -168,46 +172,50 @@ exports[`ItemHeaderSection > should match snapshot with artists 1`] = ` class="w-full text-xl" > by  - - - Darkthrone - + - , + + Darkthrone + + + , + - - - - Darkthrone - - , + + Darkthrone + + + , + - - - - Darkthrone - - , + + Darkthrone + + + , + + + + + Darkthrone + - - - - Darkthrone -
diff --git a/tests/snapshots/item-top-card.spec.tsx.snap b/tests/snapshots/item-top-card.spec.tsx.snap index 793a116c..6c9b2074 100644 --- a/tests/snapshots/item-top-card.spec.tsx.snap +++ b/tests/snapshots/item-top-card.spec.tsx.snap @@ -384,13 +384,17 @@ exports[`ItemTopCard > should match snapshot as top 2 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as top 2 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as top 3 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as top 3 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track with play time 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track with play time 1`] = ` Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track with play time and plays 1 Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot as track with play time and plays 1 Track 1

- - - Darkthrone - + + + + Darkthrone + +
should match snapshot with artists 1`] = ` class="flex w-full items-center justify-between" >
- - - Darkthrone - + - , + + Darkthrone + + + , + - - - - Mayhem - - , + + Mayhem + + + , + - - - - Darkthrone - - , + + Darkthrone + + + , + + + + + Darkthrone + - - - - Darkthrone -