393 lines
18 KiB
TypeScript
393 lines
18 KiB
TypeScript
import React from "react";
|
||
import { Navigation } from "../components/Navigation";
|
||
import { Footer } from "../components/Footer";
|
||
import { Button } from "../components/ui/button";
|
||
import { Badge } from "../components/ui/badge";
|
||
import { Card, CardContent } from "../components/ui/card";
|
||
import { Avatar, AvatarFallback, AvatarImage } from "../components/ui/avatar";
|
||
import { Separator } from "../components/ui/separator";
|
||
import { Calendar, Clock, User, ArrowRight, Share2, Linkedin, Twitter, ExternalLink, Tag } from "lucide-react";
|
||
import { navigateTo } from "../App";
|
||
import { ImageWithFallback } from "../components/figma/ImageWithFallback";
|
||
|
||
// Mock article data - in real implementation, this would come from props or API
|
||
const articleData = {
|
||
id: "ux-review-presentations",
|
||
title: "UX Review Presentations: How to Create Compelling Presentations That Win",
|
||
excerpt: "Learn how to create compelling presentations that wow clients and actually close projects and deals. Here are the key insights that will elevate your presentation game.",
|
||
content: `
|
||
<p>Creating compelling UX review presentations is both an art and a science. In today's competitive landscape, it's not enough to simply showcase your design work – you need to tell a story that resonates with stakeholders and drives decision-making.</p>
|
||
|
||
<h2>The Foundation of Great Presentations</h2>
|
||
<p>Every successful presentation starts with understanding your audience. Are you presenting to executives who care about business metrics? Developers who need technical specifications? Or end-users who want to see how the design solves their problems?</p>
|
||
|
||
<blockquote>
|
||
"The best presentations don't just show what you've designed – they show why it matters."
|
||
</blockquote>
|
||
|
||
<h3>Key Elements to Include</h3>
|
||
<ul>
|
||
<li><strong>Problem Statement:</strong> Clearly articulate the challenge you're solving</li>
|
||
<li><strong>Research Insights:</strong> Show the data that informed your decisions</li>
|
||
<li><strong>Design Process:</strong> Walk through your methodology and iterations</li>
|
||
<li><strong>Solution Overview:</strong> Present your final design with clear rationale</li>
|
||
<li><strong>Impact Metrics:</strong> Demonstrate measurable business value</li>
|
||
</ul>
|
||
|
||
<h2>Structuring Your Narrative</h2>
|
||
<p>The most compelling presentations follow a clear narrative arc. Start with the problem, build tension by exploring the challenges, and then provide resolution through your design solution. This storytelling approach keeps your audience engaged and makes your work memorable.</p>
|
||
|
||
<h3>Visual Hierarchy and Flow</h3>
|
||
<p>Your slides should guide the viewer's eye naturally from one point to the next. Use:</p>
|
||
<ol>
|
||
<li>Consistent typography and spacing</li>
|
||
<li>Strategic use of color to highlight key points</li>
|
||
<li>Progressive disclosure to build understanding</li>
|
||
<li>High-quality visuals that support your narrative</li>
|
||
</ol>
|
||
|
||
<h2>Handling Questions and Feedback</h2>
|
||
<p>Prepare for common questions and objections. Have backup slides ready with additional details, alternative approaches, and data to support your recommendations. Remember, questions are opportunities to demonstrate your expertise and build confidence in your solution.</p>
|
||
|
||
<h3>Tools and Best Practices</h3>
|
||
<p>While tools like Figma, Sketch, and Adobe XD are excellent for design work, consider presentation-specific tools like Pitch, Keynote, or PowerPoint for final delivery. Each has unique strengths for different presentation contexts.</p>
|
||
|
||
<p>The key to success is practice, preparation, and genuine enthusiasm for your work. When you believe in your solution, that confidence will shine through and convince your audience to believe in it too.</p>
|
||
`,
|
||
author: {
|
||
name: "Olivia Rhye",
|
||
title: "Senior UX Designer",
|
||
avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b47c?w=150&h=150&fit=crop&crop=face&auto=format",
|
||
bio: "Olivia is a Senior UX Designer at WDI with over 8 years of experience creating user-centered digital experiences. She specializes in design systems and has led UX initiatives for Fortune 500 companies."
|
||
},
|
||
publishDate: "December 15, 2024",
|
||
readTime: "8 min read",
|
||
category: "Design",
|
||
tags: ["UX Design", "Presentations", "Client Management", "Design Process"],
|
||
bannerImage: "https://images.unsplash.com/photo-1560472355-536de3962603?w=1200&h=600&fit=crop&auto=format",
|
||
relatedArticles: [
|
||
{
|
||
id: "migrating-linear",
|
||
title: "Migrating to Linear 101",
|
||
excerpt: "Linear helps streamline software projects, sprints, tasks, and bug tracking. Here's how to get started.",
|
||
readTime: "6 min read",
|
||
image: "https://images.unsplash.com/photo-1551434678-e076c223a692?w=400&h=250&fit=crop&auto=format",
|
||
category: "Tools"
|
||
},
|
||
{
|
||
id: "api-stack",
|
||
title: "Building Your API Stack",
|
||
excerpt: "The rise of RESTful APIs has been met by a rise in tools for creating, testing, and managing them.",
|
||
readTime: "12 min read",
|
||
image: "https://images.unsplash.com/photo-1555949963-ff9fe0c870eb?w=400&h=250&fit=crop&auto=format",
|
||
category: "Development"
|
||
},
|
||
{
|
||
id: "design-systems",
|
||
title: "Creating Scalable Design Systems",
|
||
excerpt: "Learn how to build design systems that scale across teams and products while maintaining consistency.",
|
||
readTime: "10 min read",
|
||
image: "https://images.unsplash.com/photo-1558655146-9f40138edfeb?w=400&h=250&fit=crop&auto=format",
|
||
category: "Design"
|
||
}
|
||
]
|
||
};
|
||
|
||
export const ArticleDetail = () => {
|
||
const handleShare = (platform: string) => {
|
||
const url = encodeURIComponent(window.location.href);
|
||
const title = encodeURIComponent(articleData.title);
|
||
|
||
let shareUrl = '';
|
||
switch (platform) {
|
||
case 'linkedin':
|
||
shareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`;
|
||
break;
|
||
case 'twitter':
|
||
shareUrl = `https://twitter.com/intent/tweet?url=${url}&text=${title}`;
|
||
break;
|
||
case 'whatsapp':
|
||
shareUrl = `https://wa.me/?text=${title} ${url}`;
|
||
break;
|
||
}
|
||
|
||
if (shareUrl) {
|
||
window.open(shareUrl, '_blank', 'width=600,height=400');
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="dark min-h-screen bg-background">
|
||
<Navigation />
|
||
|
||
{/* Hero Section */}
|
||
<section className="pt-24 pb-16 bg-background">
|
||
<div className="container mx-auto px-6 lg:px-8">
|
||
<div className="max-w-4xl mx-auto">
|
||
{/* Breadcrumb */}
|
||
<div className="flex items-center gap-2 text-sm text-muted-foreground mb-8">
|
||
<button onClick={() => navigateTo('/')} className="hover:text-white transition-colors">
|
||
Home
|
||
</button>
|
||
<span>/</span>
|
||
<button onClick={() => navigateTo('/resources/blog')} className="hover:text-white transition-colors">
|
||
Blog
|
||
</button>
|
||
<span>/</span>
|
||
<span className="text-white">{articleData.title}</span>
|
||
</div>
|
||
|
||
{/* Article Meta */}
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Badge variant="secondary" className="bg-[#E5195E]/20 text-[#E5195E] border-none">
|
||
{articleData.category}
|
||
</Badge>
|
||
<div className="flex items-center gap-4 text-sm text-muted-foreground">
|
||
<div className="flex items-center gap-1">
|
||
<Calendar className="w-4 h-4" />
|
||
{articleData.publishDate}
|
||
</div>
|
||
<div className="flex items-center gap-1">
|
||
<Clock className="w-4 h-4" />
|
||
{articleData.readTime}
|
||
</div>
|
||
<div className="flex items-center gap-1">
|
||
<User className="w-4 h-4" />
|
||
{articleData.author.name}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Title */}
|
||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6 text-white leading-tight">
|
||
{articleData.title}
|
||
</h1>
|
||
|
||
{/* Excerpt */}
|
||
<p className="text-xl text-muted-foreground mb-8 leading-relaxed">
|
||
{articleData.excerpt}
|
||
</p>
|
||
|
||
{/* Banner Image */}
|
||
{articleData.bannerImage && (
|
||
<div className="aspect-[16/9] overflow-hidden rounded-lg mb-8">
|
||
<ImageWithFallback
|
||
src={articleData.bannerImage}
|
||
alt={articleData.title}
|
||
className="w-full h-full object-cover"
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Main Content */}
|
||
<section className="py-16 bg-card/50">
|
||
<div className="container mx-auto px-6 lg:px-8">
|
||
<div className="grid lg:grid-cols-10 gap-12 max-w-7xl mx-auto">
|
||
|
||
{/* Article Content - 70% */}
|
||
<article className="lg:col-span-7">
|
||
<Card className="bg-background/50 border-white/10">
|
||
<CardContent className="p-8 lg:p-12">
|
||
{/* Article Body */}
|
||
<div
|
||
className="prose prose-invert prose-lg max-w-none
|
||
prose-headings:text-white prose-headings:font-semibold
|
||
prose-h2:text-3xl prose-h2:mt-12 prose-h2:mb-6
|
||
prose-h3:text-2xl prose-h3:mt-8 prose-h3:mb-4
|
||
prose-p:text-muted-foreground prose-p:leading-relaxed prose-p:mb-6
|
||
prose-strong:text-white prose-strong:font-semibold
|
||
prose-ul:text-muted-foreground prose-ul:space-y-2
|
||
prose-ol:text-muted-foreground prose-ol:space-y-2
|
||
prose-li:leading-relaxed
|
||
prose-blockquote:border-l-4 prose-blockquote:border-[#E5195E]
|
||
prose-blockquote:bg-card/50 prose-blockquote:rounded-r-lg
|
||
prose-blockquote:py-4 prose-blockquote:px-6 prose-blockquote:my-8
|
||
prose-blockquote:text-white prose-blockquote:font-medium prose-blockquote:italic
|
||
prose-blockquote:text-xl prose-blockquote:not-italic"
|
||
dangerouslySetInnerHTML={{ __html: articleData.content }}
|
||
/>
|
||
|
||
{/* Article Footer */}
|
||
<div className="mt-16 pt-8 border-t border-white/10">
|
||
{/* Tags */}
|
||
<div className="mb-8">
|
||
<h4 className="text-white font-semibold mb-4 flex items-center gap-2">
|
||
<Tag className="w-4 h-4" />
|
||
Tags
|
||
</h4>
|
||
<div className="flex flex-wrap gap-2">
|
||
{articleData.tags.map((tag) => (
|
||
<Badge key={tag} variant="outline" className="border-white/20 text-white/70">
|
||
{tag}
|
||
</Badge>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Share */}
|
||
<div className="mb-8">
|
||
<h4 className="text-white font-semibold mb-4 flex items-center gap-2">
|
||
<Share2 className="w-4 h-4" />
|
||
Share this article
|
||
</h4>
|
||
<div className="flex gap-3">
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => handleShare('linkedin')}
|
||
className="border-white/20 text-white hover:bg-blue-600/20"
|
||
>
|
||
<Linkedin className="w-4 h-4 mr-2" />
|
||
LinkedIn
|
||
</Button>
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => handleShare('twitter')}
|
||
className="border-white/20 text-white hover:bg-blue-400/20"
|
||
>
|
||
<Twitter className="w-4 h-4 mr-2" />
|
||
Twitter
|
||
</Button>
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => handleShare('whatsapp')}
|
||
className="border-white/20 text-white hover:bg-green-600/20"
|
||
>
|
||
<ExternalLink className="w-4 h-4 mr-2" />
|
||
WhatsApp
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Author Bio */}
|
||
{/* <Card className="bg-card/50 border-white/10">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<Avatar className="w-16 h-16">
|
||
<AvatarImage src={articleData.author.avatar} alt={articleData.author.name} />
|
||
<AvatarFallback>{articleData.author.name.split(' ').map(n => n[0]).join('')}</AvatarFallback>
|
||
</Avatar>
|
||
<div className="flex-1">
|
||
<h4 className="text-white font-semibold mb-1">{articleData.author.name}</h4>
|
||
<p className="text-[#E5195E] text-sm mb-3">{articleData.author.title}</p>
|
||
<p className="text-muted-foreground text-sm leading-relaxed">{articleData.author.bio}</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card> */}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</article>
|
||
|
||
{/* Sidebar - 30% */}
|
||
<aside className="lg:col-span-3 space-y-8">
|
||
|
||
{/* Related Articles */}
|
||
<Card className="bg-background/50 border-white/10">
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold text-white mb-6">You Might Also Like</h3>
|
||
<div className="space-y-6">
|
||
{articleData.relatedArticles.map((article) => (
|
||
<div
|
||
key={article.id}
|
||
className="group cursor-pointer"
|
||
onClick={() => navigateTo(`/articles/${article.id}`)}
|
||
>
|
||
<div className="aspect-[16/10] overflow-hidden rounded-lg mb-3">
|
||
<ImageWithFallback
|
||
src={article.image}
|
||
alt={article.title}
|
||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
||
/>
|
||
</div>
|
||
<Badge variant="secondary" className="bg-[#E5195E]/20 text-[#E5195E] text-xs mb-2">
|
||
{article.category}
|
||
</Badge>
|
||
<h4 className="text-white font-medium leading-tight mb-2 group-hover:text-[#E5195E] transition-colors">
|
||
{article.title}
|
||
</h4>
|
||
<p className="text-muted-foreground text-sm mb-2 line-clamp-2">{article.excerpt}</p>
|
||
<span className="text-muted-foreground text-xs">{article.readTime}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
<Separator className="my-6" />
|
||
|
||
<Button
|
||
variant="outline"
|
||
className="w-full border-white/20 text-white hover:bg-white/10"
|
||
onClick={() => navigateTo('/resources/blog')}
|
||
>
|
||
View All Articles
|
||
<ArrowRight className="w-4 h-4 ml-2" />
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Company Info */}
|
||
<Card className="bg-background/50 border-white/10">
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold text-white mb-4">About WDI</h3>
|
||
<p className="text-muted-foreground text-sm leading-relaxed mb-4">
|
||
Web Development Institute helps startups and enterprises build scalable, secure digital products.
|
||
With 25+ years of experience, we've delivered 200+ successful projects across 15+ countries.
|
||
</p>
|
||
<Button
|
||
className="w-full bg-[#E5195E] hover:bg-[#E5195E]/90 text-white"
|
||
onClick={() => navigateTo('/contact')}
|
||
>
|
||
Get In Touch
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* CTA Section */}
|
||
<section className="py-16 bg-background">
|
||
<div className="container mx-auto px-6 lg:px-8">
|
||
<Card className="max-w-4xl mx-auto bg-card/50 border-white/10">
|
||
<CardContent className="p-8 text-center">
|
||
<h2 className="text-3xl font-bold text-white mb-4">
|
||
Enjoyed this article? Let's talk.
|
||
</h2>
|
||
<p className="text-muted-foreground mb-8 max-w-2xl mx-auto">
|
||
Ready to transform your ideas into reality? Our team of experts is here to help you build
|
||
exceptional digital products that drive results.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||
<Button
|
||
size="lg"
|
||
className="bg-[#E5195E] hover:bg-[#E5195E]/90 text-white"
|
||
onClick={() => navigateTo('/contact')}
|
||
>
|
||
Start Your Project
|
||
<ArrowRight className="ml-2 w-4 h-4" />
|
||
</Button>
|
||
<Button
|
||
size="lg"
|
||
variant="outline"
|
||
className="border-white/20 text-white hover:bg-white/10"
|
||
onClick={() => navigateTo('/resources/blog')}
|
||
>
|
||
Read More Articles
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</section>
|
||
|
||
<Footer />
|
||
</div>
|
||
);
|
||
}; |