Skip to content

Commit 7a77168

Browse files
refactor: enhance PlayCard and Like components for improved UI and functionality (#1605)
* refactor: enhance PlayCard and Like components for improved UI and functionality - Updated Like component to use button type and improved styling. - Refactored PlayCard to include language badges, better avatar handling, and description truncation. - Adjusted CSS for play card hover effects and card header styling. - Added line clamp utility for text truncation in PlayCard description. - Enhanced PlayShare button with consistent sizing. * style: update playlist card width for improved layout --------- Co-authored-by: Priyankar Pal <88102392+priyankarpal@users.noreply.github.com>
1 parent 6a1ab7a commit 7a77168

File tree

4 files changed

+126
-52
lines changed

4 files changed

+126
-52
lines changed

src/common/components/Like/Like.jsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ const Like = ({ onLikeClick, likeObj }) => {
88
};
99

1010
return (
11-
<button className="action counted -mr-0.5" onClick={likeClickHandler}>
12-
<AiOutlineLike className={liked ? 'hidden' : 'icon'} size="24px" />
13-
<AiFillLike className={liked ? 'icon' : 'hidden'} size="24px" />
14-
{number > 0 ? <div className="count-value">{number}</div> : <div />}
11+
<button
12+
className="inline-flex items-center gap-1 -mr-0.5"
13+
type="button"
14+
onClick={likeClickHandler}
15+
>
16+
<AiOutlineLike className={liked ? 'hidden' : 'icon'} size={24} />
17+
<AiFillLike className={liked ? 'icon' : 'hidden'} size={24} />
18+
{number > 0 && <span className="text-sm leading-none align-middle">{number}</span>}
1519
</button>
1620
);
1721
};

src/common/playlists/PlayCard.jsx

Lines changed: 100 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,122 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { Link } from 'react-router-dom';
33
import { BsPlayCircleFill } from 'react-icons/bs';
44
import { BiLogoTypescript, BiLogoJavascript } from 'react-icons/bi';
55
import PlayShare from './PlayShare.jsx';
6-
7-
import Shimmer from 'react-shimmer-effect';
86
import Like from 'common/components/Like/Like';
97
import userImage from 'images/user.png';
108

9+
const formatDate = (dateString) => dateString || '';
10+
1111
function PlayCard({ play, cover, likeObject }) {
12-
return (
13-
<Link to={`/plays/${encodeURI(play.github.toLowerCase())}/${play.slug}`}>
14-
<div className="play-card-container">
15-
<div className="play-thumb-container">
16-
<Shimmer>
17-
<img alt="" className="play-card-thumb-img" src={cover} />
18-
</Shimmer>
19-
<BsPlayCircleFill className="play-icon" color="white" size={80} />
12+
const [isExpanded, setIsExpanded] = useState(false);
13+
if (!play || !play.github || !play.slug) return null;
14+
15+
const avatarSrc =
16+
play?.user?.avatarUrl && play.user.avatarUrl.length ? play.user.avatarUrl : userImage;
17+
18+
const LanguageBadge = () => {
19+
if (play.language === 'ts') {
20+
return (
21+
<div className="flex items-start space-x-1 bg-blue-100 text-blue-800 text-xs font-semibold px-2.5 py-0.5 rounded-md w-fit mb-3">
22+
<BiLogoTypescript color="#007acc" size={16} />
23+
<span>Typescript</span>
2024
</div>
25+
);
26+
}
27+
if (play.language === 'js') {
28+
return (
29+
<div className="flex items-start space-x-1 bg-yellow-100 text-yellow-800 text-xs font-semibold px-2.5 py-0.5 rounded-md w-fit mb-3">
30+
<BiLogoJavascript color="#F0DB4F" size={16} />
31+
<span>Javascript</span>
32+
</div>
33+
);
34+
}
35+
36+
return null;
37+
};
38+
39+
const linkTo = `/plays/${encodeURI(play.github.toLowerCase())}/${play.slug}`;
2140

22-
{/* <div className="border" /> */}
23-
<div className="card-header">{play.name}</div>
24-
{play.user && (
25-
<div className="author">
26-
<img
27-
alt="avatar"
28-
className="rounded-full border border-zink"
29-
height="25px"
30-
loading="lazy"
31-
src={
32-
play?.user.avatarUrl
33-
? play?.user.avatarUrl.length
34-
? play?.user.avatarUrl
35-
: userImage
36-
: userImage
37-
}
38-
width="25px"
41+
return (
42+
<Link className="group block" to={linkTo}>
43+
<div className="play-card-container max-w-sm bg-white rounded-xl overflow-hidden flex flex-col h-full">
44+
{cover && (
45+
<div className="relative h-48">
46+
<img alt={play.name} className="w-full h-full object-cover" src={cover} />
47+
<div className="absolute inset-0 thumb-overlay pointer-events-none" />
48+
<BsPlayCircleFill
49+
className="absolute inset-0 m-auto z-10 opacity-0 transition-opacity duration-200 pointer-events-none"
50+
color="white"
51+
size={80}
3952
/>
40-
<div className="author-name">{play?.user.displayName}</div>
4153
</div>
4254
)}
43-
<div className="play-actions mt-4">
44-
<div className="like-container">
45-
<Like likeObj={likeObject()} onLikeClick={null} />
46-
<div style={{ display: 'flex', alignItems: 'center' }}>
47-
<PlayShare
48-
cover={cover}
49-
link={`/plays/${encodeURI(play.github.toLowerCase())}/${play.slug}`}
55+
56+
<div className="p-5 flex flex-col flex-grow">
57+
<LanguageBadge />
58+
59+
{play.user?.displayName && (
60+
<div className="flex items-center text-sm text-gray-600 mb-4">
61+
<img
62+
alt="avatar"
63+
className="rounded-full h-6 w-6 object-cover mr-2"
64+
loading="lazy"
65+
src={avatarSrc}
5066
/>
51-
{play.language === 'ts' ? (
52-
<BiLogoTypescript className="lang-icon" color="#007acc" size={25} />
53-
) : (
54-
<BiLogoJavascript className="lang-icon" color="#F0DB4F" size={25} />
67+
<span className="font-semibold text-gray-800">{play.user.displayName}</span>
68+
{play.date && (
69+
<>
70+
<span className="mx-2"></span>
71+
<span className="text-gray-500">{formatDate(play.date)}</span>
72+
</>
5573
)}
5674
</div>
75+
)}
76+
77+
<div className="card-header text-md font-bold text-gray-900 mb-2">{play.name}</div>
78+
79+
{play.description && (
80+
<div className="mb-6 flex-grow">
81+
<p className={`text-gray-700 text-xs ${!isExpanded ? 'line-clamp-3' : ''}`}>
82+
{play.description}
83+
</p>
84+
</div>
85+
)}
86+
87+
<div className="mt-auto flex items-center justify-between pt-4 border-t border-gray-100">
88+
{likeObject &&
89+
(() => {
90+
const data = likeObject?.();
91+
92+
return (
93+
<div className="inline-flex items-center gap-2 whitespace-nowrap">
94+
<Like likeObj={data} onLikeClick={null} />
95+
</div>
96+
);
97+
})()}
98+
99+
<div className="flex items-center gap-3">
100+
<div className="flex items-center gap-3" onClick={(e) => e.preventDefault()}>
101+
<PlayShare cover={cover} link={linkTo} />
102+
</div>
103+
</div>
57104
</div>
58105
</div>
59106
</div>
107+
108+
<style>
109+
{`
110+
.group:hover .play-card-container .relative .z-10 { opacity: 1; }
111+
112+
.group:hover .play-card-container .relative .thumb-overlay {
113+
background-color: rgba(0, 0, 0, 0.4);
114+
backdrop-filter: blur(6px);
115+
-webkit-backdrop-filter: blur(6px);
116+
transition: background-color 200ms ease, backdrop-filter 200ms ease;
117+
}
118+
`}
119+
</style>
60120
</Link>
61121
);
62122
}

src/common/playlists/PlayShare.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function PlayShare({ cover, link }) {
115115
setShowModal(true);
116116
}}
117117
>
118-
<IoShareOutline className="mx-2" />
118+
<IoShareOutline className="mx-2 w-6 h-6" />
119119
</button>
120120
</div>
121121
);

src/common/playlists/playlist.css

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -842,17 +842,18 @@
842842
position: relative;
843843
display: flex;
844844
flex-direction: column;
845-
border: 2px solid #757575;
845+
border: 2px solid #efefef;
846846
border-radius: 8px;
847847
overflow: hidden;
848848
transition: transform 0.2s ease-in-out;
849-
width: 300px;
850-
height: 100%;
849+
width: 350px;
850+
/* height: 100%; */
851851
padding: 12px;
852852
}
853853

854854
.play-card-container:hover {
855-
transform: scale(105%);
855+
transform: scale(103%);
856+
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.2);
856857
transition: transform 0.2s ease-in-out;
857858
}
858859

@@ -881,9 +882,9 @@
881882
font-weight: 200;
882883
}
883884
.card-header {
884-
font-size: 18px;
885-
padding: 10px;
886-
text-align: center;
885+
font-size: 15px;
886+
padding: 10px 0px;
887+
text-align: start;
887888
}
888889

889890
.img {
@@ -960,3 +961,12 @@
960961
.play-card-container:hover .lang-icon {
961962
filter: none;
962963
}
964+
965+
/* Line clamp utility for text truncation */
966+
.line-clamp-3 {
967+
display: -webkit-box;
968+
-webkit-line-clamp: 3;
969+
line-clamp: 3;
970+
-webkit-box-orient: vertical;
971+
overflow: hidden;
972+
}

0 commit comments

Comments
 (0)