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":
+ ,
+ "container":
-
+