@@ -25,6 +25,24 @@ const SocialMediaPreviewer = () => {
2525 return 'manual' ;
2626 } ) ;
2727
28+ useEffect ( ( ) => {
29+ if ( ! imageUrl ) {
30+ setImageDimensions ( { width : 0 , height : 0 } ) ;
31+ return ;
32+ }
33+
34+ const img = new Image ( ) ;
35+ img . src = imageUrl ;
36+
37+ img . onload = ( ) => {
38+ setImageDimensions ( { width : img . width , height : img . height } ) ;
39+ } ;
40+
41+ img . onerror = ( ) => {
42+ setImageDimensions ( { width : 0 , height : 0 } ) ;
43+ } ;
44+ } , [ imageUrl ] ) ;
45+
2846 useEffect ( ( ) => {
2947 if ( imageSource === 'upload' && uploadedImage ) {
3048 const reader = new FileReader ( ) ;
@@ -169,11 +187,12 @@ const SocialMediaPreviewer = () => {
169187 const TwitterCard = ( ) => {
170188 const isLarge = twitterCardType === 'summary_large_image' ;
171189 return (
172- < div className = "border border-gray-300 rounded-lg overflow-hidden bg-white max-w-sm mx-auto font-sans text-black" >
190+ < div className = "border border-gray-300 rounded-xl overflow-hidden bg-white max-w-sm mx-auto font-sans text-black" >
173191 { isLarge ? (
174192 < >
175193 { imageUrl && (
176- < div className = "h-48 overflow-hidden bg-gray-100 relative" >
194+ // Twitter Large: ~1.91:1 Aspect Ratio
195+ < div className = "w-full relative aspect-[1.91/1] bg-gray-100" >
177196 < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover" />
178197 </ div >
179198 ) }
@@ -184,13 +203,13 @@ const SocialMediaPreviewer = () => {
184203 </ div >
185204 </ >
186205 ) : (
187- < div className = "flex" >
206+ < div className = "flex items-center " >
188207 { imageUrl && (
189- < div className = "w-32 h-32 flex- shrink-0 bg-gray-100 relative border-r border-gray-200" >
208+ < div className = "w-32 shrink-0 aspect-square bg-gray-100 border-r border-gray-200 relative " >
190209 < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover" />
191210 </ div >
192211 ) }
193- < div className = "p-3 flex flex-col justify-center overflow-hidden" >
212+ < div className = "p-3 overflow-hidden" >
194213 < div className = "text-gray-500 text-sm uppercase truncate mb-1" > { getDomainName ( url ) } </ div >
195214 < div className = "font-bold text-gray-900 leading-tight mb-1 truncate" > { title || 'Page Title' } </ div >
196215 < div className = "text-gray-500 text-sm line-clamp-2" > { description || 'Page description goes here...' } </ div >
@@ -202,13 +221,13 @@ const SocialMediaPreviewer = () => {
202221 } ;
203222
204223 const FacebookCard = ( ) => (
205- < div className = "border border-gray-300 bg-gray-100 max-w-sm mx-auto font-sans text-black" >
224+ < div className = "border border-gray-300 bg-[#f0f2f5] max-w-sm mx-auto font-sans text-black" >
206225 { imageUrl && (
207- < div className = "h-48 overflow-hidden bg-gray-200 relative" >
226+ < div className = "w-full aspect-[1.91/1] bg-gray-200 relative" >
208227 < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover" />
209228 </ div >
210229 ) }
211- < div className = "p-3 bg-gray-100 border-t border-gray-300" >
230+ < div className = "p-3 bg-[#f0f2f5] border-t border-gray-300" >
212231 < div className = "text-gray-600 text-xs uppercase truncate mb-1" > { getDomainName ( url ) . toUpperCase ( ) } </ div >
213232 < div className = "font-bold text-gray-900 leading-tight mb-1 line-clamp-2" > { title || 'Page Title' } </ div >
214233 < div className = "text-gray-600 text-sm line-clamp-1" > { description || 'Page description goes here...' } </ div >
@@ -219,7 +238,7 @@ const SocialMediaPreviewer = () => {
219238 const LinkedInCard = ( ) => (
220239 < div className = "border border-gray-300 rounded-sm overflow-hidden bg-white max-w-sm mx-auto font-sans text-black shadow-sm" >
221240 { imageUrl && (
222- < div className = "h-48 overflow-hidden bg-gray-100 relative" >
241+ < div className = "w-full aspect-[1.91/1] bg-gray-100 relative" >
223242 < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover" />
224243 </ div >
225244 ) }
@@ -236,18 +255,18 @@ const SocialMediaPreviewer = () => {
236255 < div className = "font-bold text-[#00b0f4] mb-1 hover:underline cursor-pointer" > { title || 'Page Title' } </ div >
237256 < div className = "text-sm text-gray-300 mb-2 line-clamp-3" > { description || 'Page description goes here...' } </ div >
238257 { imageUrl && (
239- < div className = "rounded-lg overflow-hidden max-w-full max-h-60 bg-gray-900 inline-block" >
240- < img src = { imageUrl } alt = "Preview" className = "max- w-full h-auto object-contain max-h-60 " />
258+ < div className = "rounded-lg overflow-hidden max-w-[90%] bg-gray-900 inline-block" >
259+ < img src = { imageUrl } alt = "Preview" className = "w-full h-auto object-contain max-h-[250px] " />
241260 </ div >
242261 ) }
243262 </ div >
244263 ) ;
245264
246265 const WhatsAppCard = ( ) => (
247- < div className = "bg-[#dcf8c6] p-2 rounded-lg max-w-sm mx-auto font-sans text-black shadow relative inline-block" >
266+ < div className = "bg-[#dcf8c6] p-2 rounded-lg max-w-sm mx-auto font-sans text-black shadow relative inline-block min-w-[280px] " >
248267 < div className = "bg-gray-100 rounded overflow-hidden mb-1" >
249268 { imageUrl && (
250- < div className = "h-32 overflow-hidden bg-gray-200 relative" >
269+ < div className = "w-full aspect-[1.91/1] bg-gray-200 relative" >
251270 < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover" />
252271 </ div >
253272 ) }
@@ -257,23 +276,30 @@ const SocialMediaPreviewer = () => {
257276 < div className = "text-gray-500 text-xs truncate mt-1" > { getDomainName ( url ) } </ div >
258277 </ div >
259278 </ div >
260- < div className = "text-blue-500 hover:underline text-sm break-all" > { url || 'https://example.com' } </ div >
279+ < div className = "text-blue-500 hover:underline text-sm break-all px-1 " > { url || 'https://example.com' } </ div >
261280 </ div >
262281 ) ;
263282
264283 const TelegramCard = ( ) => (
265- < div className = "bg-white p-2 rounded-lg max-w-sm mx-auto font-sans text-black shadow-sm border border-gray-100 inline-block" >
284+ < div className = "bg-white p-2 rounded-lg max-w-sm mx-auto font-sans text-black shadow-sm border border-gray-100 inline-block min-w-[280px] " >
266285 < div className = "font-bold text-[#2481cc] leading-tight mb-1 cursor-pointer truncate" > { title || 'Page Title' } </ div >
267286 < div className = "text-black text-sm mb-2 line-clamp-3 leading-snug" > { description || 'Page description goes here...' } </ div >
268287 { imageUrl && (
269- < div className = "rounded overflow-hidden mb-1 relative" >
270- < img src = { imageUrl } alt = "Preview" className = "w-full h-auto object-cover rounded" />
288+ < div className = "rounded overflow-hidden mb-1 relative w-full aspect-[1.91/1] " >
289+ < img src = { imageUrl } alt = "Preview" className = "w-full h-full object-cover rounded" />
271290 </ div >
272291 ) }
273292 < div className = "text-blue-500 text-sm truncate opacity-70 mt-1" > { getDomainName ( url ) } </ div >
274293 </ div >
275294 ) ;
276295
296+ const WrapOgCard = ( { label, children } ) => (
297+ < div className = "flex flex-col gap-2 border border-white/70 p-1 pb-3 rounded-2xl" >
298+ < h3 className = "text-lg font-semibold text-gray-300 mb-1 ml-4" > { label } </ h3 >
299+ { children }
300+ </ div >
301+ ) ;
302+
277303
278304 return (
279305 < ToolBoxLayout >
@@ -364,6 +390,18 @@ const SocialMediaPreviewer = () => {
364390 ) }
365391 </ div >
366392 ) }
393+
394+ { /* Image Dimensions Display */ }
395+ { imageUrl && imageDimensions . width > 0 && (
396+ < div className = "text-xs text-gray-400 mt-2 flex items-center gap-1" >
397+ < span className = "bg-gray-800 px-2 py-0.5 rounded border border-gray-700" >
398+ { imageDimensions . width } x { imageDimensions . height } px
399+ </ span >
400+ { imageDimensions . width < 200 || imageDimensions . height < 200 ? (
401+ < span className = "text-yellow-500 ml-1" > (Low Res)</ span >
402+ ) : null }
403+ </ div >
404+ ) }
367405 </ div >
368406
369407 < Input
@@ -460,35 +498,16 @@ const SocialMediaPreviewer = () => {
460498 { /* here can be used loop */ }
461499 < ToolBox title = "Previews" boxWidth = "60%" >
462500 < div className = "grid grid-cols-1 md:grid-cols-2 gap-6 pb-8" >
463- < div className = "flex flex-col gap-2" >
464- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > Twitter / X</ h3 >
465- < TwitterCard />
466- </ div >
467-
468- < div className = "flex flex-col gap-2" >
469- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > Facebook</ h3 >
470- < FacebookCard />
471- </ div >
472-
473- < div className = "flex flex-col gap-2" >
474- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > LinkedIn</ h3 >
475- < LinkedInCard />
476- </ div >
477-
478- < div className = "flex flex-col gap-2" >
479- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > Discord</ h3 >
480- < DiscordCard />
481- </ div >
482-
483- < div className = "flex flex-col gap-2" >
484- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > WhatsApp</ h3 >
485- < WhatsAppCard />
486- </ div >
487-
488- < div className = "flex flex-col gap-2" >
489- < h3 className = "text-lg font-semibold text-gray-300 mb-1" > Telegram</ h3 >
490- < TelegramCard />
491- </ div >
501+ { [
502+ { id : 'twitter' , label : 'Twitter / X' , component : < TwitterCard /> } ,
503+ { id : 'facebook' , label : 'Facebook' , component : < FacebookCard /> } ,
504+ { id : 'linkedin' , label : 'LinkedIn' , component : < LinkedInCard /> } ,
505+ { id : 'discord' , label : 'Discord' , component : < DiscordCard /> } ,
506+ { id : 'whatsapp' , label : 'WhatsApp' , component : < WhatsAppCard /> } ,
507+ { id : 'telegram' , label : 'Telegram' , component : < TelegramCard /> } ,
508+ ] . map ( ( card ) => (
509+ < WrapOgCard key = { card . id } label = { card . label } > { card . component } </ WrapOgCard >
510+ ) ) }
492511 </ div >
493512 </ ToolBox >
494513 </ ToolBoxLayout >
0 commit comments