|
| 1 | +// prettier-ignore |
1 | 2 | import React from "react"; |
2 | 3 | import { motion } from "framer-motion"; |
3 | 4 | import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"; |
@@ -26,83 +27,78 @@ const TestimonialCard: React.FC<TestimonialCardProps> = ({ |
26 | 27 | const formatLinkDisplay = (url: string) => { |
27 | 28 | try { |
28 | 29 | const urlObj = new URL(url); |
29 | | - return urlObj.hostname.replace("www.", ""); |
| 30 | + return urlObj.hostname + urlObj.pathname; |
30 | 31 | } catch { |
31 | 32 | return url; |
32 | 33 | } |
33 | 34 | }; |
34 | 35 |
|
35 | 36 | return ( |
36 | 37 | <motion.div |
37 | | - initial={{ opacity: 0, y: 12 }} |
38 | | - animate={{ opacity: 1, y: 0 }} |
39 | | - exit={{ opacity: 0, y: -12 }} |
40 | | - transition={{ duration: 0.3 }} |
41 | | - className={`rounded-2xl max-h-[250px] h-[246px] p-5 shadow-md hover:shadow-lg transition-all duration-300 flex flex-col justify-between ${ |
42 | | - isDark ? "bg-[#18181b] text-white" : "bg-white text-gray-900" |
| 38 | + initial={{ opacity: 0 }} |
| 39 | + animate={{ opacity: 1 }} |
| 40 | + exit={{ opacity: 0 }} |
| 41 | + className={`rounded-2xl p-4 shadow-md hover:shadow-lg transition-shadow duration-300 flex flex-col justify-between ${ |
| 42 | + isDark ? "bg-[#1a1a1a] text-white" : "bg-white text-gray-900" |
43 | 43 | }`} |
44 | 44 | > |
45 | | - {/* Header */} |
46 | | - <div className="flex items-center gap-4"> |
47 | | - <Avatar className="w-15 h-15 border border-gray-200 dark:border-gray-700"> |
48 | | - <AvatarImage |
49 | | - className="w-15 h-15 object-cover " |
50 | | - src={avatar} |
51 | | - alt={name} |
52 | | - /> |
53 | | - <AvatarFallback>{name?.charAt(0) ?? "U"}</AvatarFallback> |
| 45 | + {/* Header with Avatar and Name */} |
| 46 | + <div className="flex items-center gap-3 "> |
| 47 | + <Avatar className="w-16 h-16 rounded-full"> |
| 48 | + <AvatarImage src={avatar} className="object-cover" /> |
| 49 | + <AvatarFallback>CN</AvatarFallback> |
54 | 50 | </Avatar> |
55 | | - <div> |
56 | | - <h3 className="font-semibold text-base">{name}</h3> |
57 | | - <p className="text-sm text-gray-500 dark:text-gray-400"> |
| 51 | + <div className="box-border p-0 m-0"> |
| 52 | + <h3 |
| 53 | + className={`font-semibold text-base ${ |
| 54 | + isDark ? "text-white" : "text-gray-900" |
| 55 | + }`} |
| 56 | + > |
| 57 | + {name} |
| 58 | + </h3> |
| 59 | + <p |
| 60 | + className={`text-sm ${isDark ? "text-gray-400" : "text-gray-500"}`} |
| 61 | + > |
58 | 62 | @{username} |
59 | 63 | </p> |
60 | 64 | </div> |
61 | 65 | </div> |
62 | 66 |
|
63 | 67 | {/* Content */} |
64 | 68 | <p |
65 | | - className={`mt-4 mb-3 text-sm leading-relaxed ${ |
66 | | - isDark ? "text-gray-300" : "text-gray-700" |
67 | | - }`} |
| 69 | + className={`line-clamp-4 ${isDark ? "text-gray-300" : "text-gray-700"}`} |
68 | 70 | > |
69 | | - {content.length > 220 ? content.slice(0, 220) + "..." : content} |
| 71 | + {content.length > 100 ? content.slice(0, 99) + "..." : content} |
70 | 72 | </p> |
71 | 73 |
|
72 | | - {/* Footer */} |
| 74 | + {/* Footer with Hashtags and Date */} |
73 | 75 | <div |
74 | | - className={`pt-3 mt-auto border-t text-sm flex flex-col gap-2 ${ |
75 | | - isDark ? "border-gray-700" : "border-gray-100" |
| 76 | + className={`flex flex-col gap-2 text-sm border-t ${ |
| 77 | + isDark ? "border-gray-700" : "border-gray-200" |
76 | 78 | }`} |
77 | 79 | > |
78 | 80 | {/* Hashtags */} |
79 | | - {content.match(/#\w+/g) && ( |
80 | | - <div className="flex flex-wrap gap-2"> |
81 | | - {content |
82 | | - .match(/#\w+/g) |
83 | | - ?.slice(0, 3) |
84 | | - .map((tag, i) => ( |
85 | | - <span |
86 | | - key={i} |
87 | | - className={`px-2 py-0.5 rounded-md text-xs font-medium ${ |
88 | | - isDark |
89 | | - ? "bg-blue-900/40 text-blue-300" |
90 | | - : "bg-blue-50 text-blue-700" |
91 | | - }`} |
92 | | - > |
93 | | - {tag} |
94 | | - </span> |
95 | | - ))} |
96 | | - </div> |
97 | | - )} |
| 81 | + <div className="flex gap-2 flex-wrap"> |
| 82 | + {content |
| 83 | + .match(/#\w+/g) |
| 84 | + ?.slice(0, 3) |
| 85 | + .map((hashtag, index) => ( |
| 86 | + <span |
| 87 | + key={index} |
| 88 | + className="text-blue-500 hover:text-blue-600 cursor-pointer" |
| 89 | + > |
| 90 | + {hashtag} |
| 91 | + </span> |
| 92 | + ))} |
| 93 | + </div> |
98 | 94 |
|
99 | | - {/* Link and Date */} |
100 | | - <div className="flex items-center justify-between"> |
| 95 | + {/* Link and Date Row */} |
| 96 | + <div className="flex items-center justify-between mt-1"> |
101 | 97 | <a |
102 | 98 | href={link} |
103 | 99 | target="_blank" |
104 | 100 | rel="noopener noreferrer" |
105 | | - className={`truncate max-w-[70%] text-sm font-medium hover:underline ${ |
| 101 | + className={`truncate max-w-[70%] hover:underline cursor-pointer ${ |
106 | 102 | isDark |
107 | 103 | ? "text-blue-400 hover:text-blue-300" |
108 | 104 | : "text-blue-600 hover:text-blue-700" |
|
0 commit comments