Skip to content

Commit 5ccace7

Browse files
author
raineer
committed
admin card redirect
1 parent b6f6968 commit 5ccace7

1 file changed

Lines changed: 74 additions & 70 deletions

File tree

‎apps/codebility/app/(marketing)/_components/landing/LandingAdminCard.tsx‎

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,81 +8,85 @@ import { useState } from "react";
88

99
// Utility function to capitalize the first letter of each word
1010
const capitalizeWords = (text: string) => {
11-
return text
12-
.split(" ")
13-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
14-
.join(" ");
11+
return text
12+
.split(" ")
13+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
14+
.join(" ");
1515
};
1616

1717
const AdminCard = ({ admin }: { admin: Codev }) => {
18-
const [imageLoaded, setImageLoaded] = useState(false);
19-
const defaultImage = "/assets/svgs/icon-codebility-black.svg";
18+
const [imageLoaded, setImageLoaded] = useState(false);
19+
const defaultImage = "/assets/svgs/icon-codebility-black.svg";
2020

21-
return (
22-
<motion.div
23-
className="h-full"
24-
>
25-
<div className="flex h-full w-full flex-col gap-4 rounded-lg">
26-
<div className="relative h-[250px] w-full rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800">
27-
{/* Image */}
28-
<div className="relative w-full h-full">
29-
<Image
30-
alt={`${admin.first_name} Avatar`}
31-
src={admin.image_url || defaultImage}
32-
fill
33-
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
34-
priority
35-
className="rounded-lg object-cover"
36-
onLoad={() => setImageLoaded(true)}
37-
onError={(e) => {
38-
e.currentTarget.src = defaultImage;
39-
}}
40-
/>
41-
</div>
21+
// Line 18: Enhanced with onClick redirect and hover effects
22+
return (
23+
<motion.div
24+
className="h-full cursor-pointer"
25+
onClick={() => window.location.href = `https://www.codebility.tech/profiles/${admin.id}`}
26+
whileHover={{ scale: 1.02 }}
27+
transition={{ duration: 0.2 }}
28+
>
29+
<div className="flex h-full w-full flex-col gap-4 rounded-lg">
30+
<div className="relative h-[250px] w-full rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800">
31+
{/* Image */}
32+
<div className="relative w-full h-full">
33+
<Image
34+
alt={`${admin.first_name} Avatar`}
35+
src={admin.image_url || defaultImage}
36+
fill
37+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
38+
priority
39+
className="rounded-lg object-cover"
40+
onLoad={() => setImageLoaded(true)}
41+
onError={(e) => {
42+
e.currentTarget.src = defaultImage;
43+
}}
44+
/>
45+
</div>
4246

43-
{/* Loading skeleton */}
44-
{!imageLoaded && (
45-
<motion.div
46-
className="absolute inset-0 bg-gradient-to-r from-gray-300 via-gray-200 to-gray-300 rounded-lg"
47-
animate={{
48-
backgroundPosition: ["200% 0", "-200% 0"],
49-
}}
50-
transition={{
51-
duration: 1.5,
52-
repeat: Infinity,
53-
ease: "linear",
54-
}}
55-
style={{
56-
backgroundSize: "200% 100%",
57-
}}
58-
/>
59-
)}
60-
</div>
47+
{/* Loading skeleton */}
48+
{!imageLoaded && (
49+
<motion.div
50+
className="absolute inset-0 bg-gradient-to-r from-gray-300 via-gray-200 to-gray-300 rounded-lg"
51+
animate={{
52+
backgroundPosition: ["200% 0", "-200% 0"],
53+
}}
54+
transition={{
55+
duration: 1.5,
56+
repeat: Infinity,
57+
ease: "linear",
58+
}}
59+
style={{
60+
backgroundSize: "200% 100%",
61+
}}
62+
/>
63+
)}
64+
</div>
6165

62-
{/* Text content */}
63-
<motion.div
64-
className="flex w-full flex-col gap-1"
65-
initial={{ opacity: 0, y: 10 }}
66-
animate={{ opacity: 1, y: 0 }}
67-
transition={{ duration: 0.5, delay: 0.2 }}
68-
>
69-
<p className="md:text-md text-sm text-white lg:text-lg font-medium">
70-
{capitalizeWords(admin.first_name)}{" "}
71-
{capitalizeWords(admin.last_name)}
72-
</p>
73-
<div className="min-h-[2.5rem]">
74-
{admin.display_position ? (
75-
<p className="text-gray-300 text-sm lg:text-base">
76-
{admin.display_position}
77-
</p>
78-
) : (
79-
<div className="text-sm lg:text-base">&nbsp;</div>
80-
)}
81-
</div>
82-
</motion.div>
83-
</div>
84-
</motion.div>
85-
);
66+
{/* Text content */}
67+
<motion.div
68+
className="flex w-full flex-col gap-1"
69+
initial={{ opacity: 0, y: 10 }}
70+
animate={{ opacity: 1, y: 0 }}
71+
transition={{ duration: 0.5, delay: 0.2 }}
72+
>
73+
<p className="md:text-md text-sm text-white lg:text-lg font-medium">
74+
{capitalizeWords(admin.first_name)}{" "}
75+
{capitalizeWords(admin.last_name)}
76+
</p>
77+
<div className="min-h-[2.5rem]">
78+
{admin.display_position ? (
79+
<p className="text-gray-300 text-sm lg:text-base">
80+
{admin.display_position}
81+
</p>
82+
) : (
83+
<div className="text-sm lg:text-base">&nbsp;</div>
84+
)}
85+
</div>
86+
</motion.div>
87+
</div>
88+
</motion.div>
89+
);
8690
};
8791

88-
export default AdminCard;
92+
export default AdminCard;

0 commit comments

Comments
 (0)