This repository has been archived on 2026-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
KLC-Learners-Portal-Fronten…/src/components/Blog.tsx
2025-09-26 19:19:50 +05:30

468 lines
17 KiB
TypeScript

import React, { useState } from 'react';
import {
Plus,
Edit,
Eye,
Trash2,
Clock,
CheckCircle,
XCircle,
AlertCircle,
Upload,
Image,
Video
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
import { Button } from './ui/button';
import { Input } from './ui/input';
import { Textarea } from './ui/textarea';
import { Badge } from './ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger
} from './ui/dialog';
import { Label } from './ui/label';
import { useAppContext } from './AppShell';
// Mock blog submissions data
const mockBlogData = [
{
id: '1',
title: 'The Future of Remote Leadership: Lessons from the Pandemic',
excerpt: 'Exploring how the COVID-19 pandemic transformed leadership approaches and what lessons we can carry forward...',
content: 'Full article content would be here...',
status: 'published',
submittedAt: '2024-08-15T10:00:00Z',
publishedAt: '2024-08-18T14:00:00Z',
views: 1247,
tags: ['Remote Leadership', 'Digital Transformation', 'Crisis Management']
},
{
id: '2',
title: 'Building Resilient Teams in Uncertain Times',
excerpt: 'Strategies for developing team resilience and maintaining high performance during periods of uncertainty...',
content: 'Full article content would be here...',
status: 'under-review',
submittedAt: '2024-09-01T15:30:00Z',
tags: ['Team Building', 'Resilience', 'Leadership']
},
{
id: '3',
title: 'Emotional Intelligence in Modern Leadership',
excerpt: 'Why EQ matters more than ever in today\'s complex business environment and how to develop it...',
content: 'Full article content would be here...',
status: 'rejected',
submittedAt: '2024-08-20T09:15:00Z',
rejectedAt: '2024-08-22T11:00:00Z',
rejectionReason: 'Content needs more original research and citations. Please add specific examples and data to support your claims.',
tags: ['Emotional Intelligence', 'Leadership Development']
},
{
id: '4',
title: 'Sustainable Leadership Practices',
excerpt: 'Draft exploring how leaders can integrate sustainability into their decision-making processes...',
content: 'Full article content would be here...',
status: 'draft',
updatedAt: '2024-09-02T16:45:00Z',
tags: ['Sustainability', 'Strategic Leadership']
}
];
export function Blog() {
const { user } = useAppContext();
const [activeTab, setActiveTab] = useState('my-posts');
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [editingPost, setEditingPost] = useState<any>(null);
const [formData, setFormData] = useState({
title: '',
excerpt: '',
content: '',
tags: ''
});
const getStatusIcon = (status: string) => {
switch (status) {
case 'published': return CheckCircle;
case 'under-review': return Clock;
case 'rejected': return XCircle;
case 'draft': return Edit;
default: return AlertCircle;
}
};
const getStatusColor = (status: string) => {
switch (status) {
case 'published': return 'bg-green-100 text-green-800';
case 'under-review': return 'bg-blue-100 text-blue-800';
case 'rejected': return 'bg-red-100 text-red-800';
case 'draft': return 'bg-gray-100 text-gray-800';
default: return 'bg-gray-100 text-gray-800';
}
};
const formatDate = (dateStr: string) => {
return new Date(dateStr).toLocaleDateString('en-IN', {
day: '2-digit',
month: 'short',
year: 'numeric',
timeZone: 'Asia/Kolkata'
});
};
const handleSubmit = () => {
// TODO: Submit blog post
console.log('Submitting:', formData);
setIsDialogOpen(false);
setFormData({ title: '', excerpt: '', content: '', tags: '' });
setEditingPost(null);
};
const BlogPostCard = ({ post }: { post: any }) => {
const StatusIcon = getStatusIcon(post.status);
return (
<Card>
<CardContent className="p-4 space-y-3">
<div className="flex items-start justify-between">
<div className="flex-1 space-y-2">
<div className="flex items-center gap-2">
<StatusIcon className="h-4 w-4" />
<Badge className={`capitalize ${getStatusColor(post.status)}`}>
{post.status.replace('-', ' ')}
</Badge>
</div>
<h3 className="font-medium">{post.title}</h3>
<p className="text-sm text-muted-foreground line-clamp-2">
{post.excerpt}
</p>
<div className="flex flex-wrap gap-1">
{post.tags.map((tag: string) => (
<Badge key={tag} variant="outline" className="text-xs">
{tag}
</Badge>
))}
</div>
<div className="flex items-center gap-4 text-xs text-muted-foreground">
<span>
Submitted {formatDate(post.submittedAt)}
</span>
{post.publishedAt && (
<span>
Published {formatDate(post.publishedAt)}
</span>
)}
{post.views && (
<span>
{post.views} views
</span>
)}
</div>
{post.rejectionReason && (
<div className="p-3 bg-red-50 border border-red-200 rounded-lg">
<p className="text-sm font-medium text-red-800 mb-1">Rejection Reason:</p>
<p className="text-sm text-red-700">{post.rejectionReason}</p>
</div>
)}
</div>
<div className="flex gap-2 ml-4">
<Button
size="icon"
variant="ghost"
onClick={() => {
setEditingPost(post);
setFormData({
title: post.title,
excerpt: post.excerpt,
content: post.content,
tags: post.tags.join(', ')
});
setIsDialogOpen(true);
}}
className="h-8 w-8"
>
<Edit className="h-3 w-3" />
</Button>
{post.status === 'published' && (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
>
<Eye className="h-3 w-3" />
</Button>
)}
<Button
size="icon"
variant="ghost"
className="h-8 w-8 text-destructive hover:text-destructive"
>
<Trash2 className="h-3 w-3" />
</Button>
</div>
</div>
</CardContent>
</Card>
);
};
return (
<div className="p-6 space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-medium">Leadership Blog</h1>
<p className="text-muted-foreground">
Share your leadership insights and experiences
</p>
</div>
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogTrigger asChild>
<Button onClick={() => {
setEditingPost(null);
setFormData({ title: '', excerpt: '', content: '', tags: '' });
}}>
<Plus className="h-4 w-4 mr-2" />
Write Article
</Button>
</DialogTrigger>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>
{editingPost ? 'Edit Article' : 'Write New Article'}
</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="title">Title</Label>
<Input
id="title"
placeholder="Enter article title..."
value={formData.title}
onChange={(e) => setFormData(prev => ({ ...prev, title: e.target.value }))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="excerpt">Excerpt</Label>
<Textarea
id="excerpt"
placeholder="Brief summary of your article..."
className="h-20"
value={formData.excerpt}
onChange={(e) => setFormData(prev => ({ ...prev, excerpt: e.target.value }))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="content">Content</Label>
<div className="border rounded-lg">
<div className="flex items-center gap-2 p-2 border-b bg-muted">
<Button size="sm" variant="ghost">
<Image className="h-4 w-4" />
</Button>
<Button size="sm" variant="ghost">
<Video className="h-4 w-4" />
</Button>
<Button size="sm" variant="ghost">
<Upload className="h-4 w-4" />
</Button>
<span className="text-xs text-muted-foreground ml-auto">
Markdown supported
</span>
</div>
<Textarea
id="content"
placeholder="Write your article content here. You can use markdown formatting and embed images/videos..."
className="min-h-[300px] border-0 resize-none focus-visible:ring-0"
value={formData.content}
onChange={(e) => setFormData(prev => ({ ...prev, content: e.target.value }))}
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="tags">Tags</Label>
<Input
id="tags"
placeholder="Leadership, Strategy, Team Building (comma separated)"
value={formData.tags}
onChange={(e) => setFormData(prev => ({ ...prev, tags: e.target.value }))}
/>
</div>
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<h4 className="font-medium text-blue-800 mb-2">Submission Guidelines</h4>
<ul className="text-sm text-blue-700 space-y-1">
<li> Articles are reviewed by our editorial team before publication</li>
<li> Focus on original insights and practical leadership advice</li>
<li> Include specific examples and actionable takeaways</li>
<li> Maintain professional tone and cite sources when needed</li>
</ul>
</div>
<div className="flex justify-end gap-2">
<Button variant="outline" onClick={() => setIsDialogOpen(false)}>
Cancel
</Button>
<Button variant="outline">
Save Draft
</Button>
<Button onClick={handleSubmit}>
{editingPost ? 'Update Article' : 'Submit for Review'}
</Button>
</div>
</div>
</DialogContent>
</Dialog>
</div>
{/* Stats Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card>
<CardContent className="p-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-green-500 flex items-center justify-center text-white">
<CheckCircle className="h-5 w-5" />
</div>
<div>
<p className="text-2xl font-bold">{mockBlogData.filter(p => p.status === 'published').length}</p>
<p className="text-sm text-muted-foreground">Published</p>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-blue-500 flex items-center justify-center text-white">
<Clock className="h-5 w-5" />
</div>
<div>
<p className="text-2xl font-bold">{mockBlogData.filter(p => p.status === 'under-review').length}</p>
<p className="text-sm text-muted-foreground">Under Review</p>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-gray-500 flex items-center justify-center text-white">
<Edit className="h-5 w-5" />
</div>
<div>
<p className="text-2xl font-bold">{mockBlogData.filter(p => p.status === 'draft').length}</p>
<p className="text-sm text-muted-foreground">Drafts</p>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-[#F8C301] flex items-center justify-center text-[#04045B]">
<Eye className="h-5 w-5" />
</div>
<div>
<p className="text-2xl font-bold">
{mockBlogData.reduce((sum, post) => sum + (post.views || 0), 0)}
</p>
<p className="text-sm text-muted-foreground">Total Views</p>
</div>
</div>
</CardContent>
</Card>
</div>
{/* Tabs */}
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-4">
<TabsList>
<TabsTrigger value="my-posts">My Submissions</TabsTrigger>
<TabsTrigger value="guidelines">Guidelines</TabsTrigger>
</TabsList>
<TabsContent value="my-posts" className="space-y-4">
{mockBlogData.length === 0 ? (
<Card>
<CardContent className="p-8 text-center">
<Edit className="h-12 w-12 mx-auto text-muted-foreground mb-4" />
<h3 className="font-medium mb-2">No articles yet</h3>
<p className="text-sm text-muted-foreground mb-4">
Start sharing your leadership insights with the community
</p>
<Button>
<Plus className="h-4 w-4 mr-2" />
Write Your First Article
</Button>
</CardContent>
</Card>
) : (
<div className="space-y-4">
{mockBlogData.map((post) => (
<BlogPostCard key={post.id} post={post} />
))}
</div>
)}
</TabsContent>
<TabsContent value="guidelines">
<Card>
<CardHeader>
<CardTitle>Article Submission Guidelines</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-4">
<div>
<h3 className="font-medium mb-2">Content Requirements</h3>
<ul className="text-sm space-y-1 text-muted-foreground">
<li> Minimum 800 words, maximum 3000 words</li>
<li> Original content with practical leadership insights</li>
<li> Include specific examples and actionable advice</li>
<li> Cite sources and provide references where applicable</li>
</ul>
</div>
<div>
<h3 className="font-medium mb-2">Review Process</h3>
<ul className="text-sm space-y-1 text-muted-foreground">
<li> Articles are reviewed within 5-7 business days</li>
<li> Editorial team may suggest revisions</li>
<li> Approved articles are published on the KLC website</li>
<li> Authors are notified of publication via email</li>
</ul>
</div>
<div>
<h3 className="font-medium mb-2">Topics We're Looking For</h3>
<ul className="text-sm space-y-1 text-muted-foreground">
<li> Strategic leadership and vision</li>
<li> Team building and management</li>
<li> Change management and innovation</li>
<li> Digital transformation leadership</li>
<li> Emotional intelligence and soft skills</li>
<li> Industry-specific leadership challenges</li>
</ul>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
);
}